Connecting Tech Pros Worldwide Help | Site Map

numeric_limits<float> questions

 
LinkBack Thread Tools Search this Thread
  #1  
Old October 31st, 2007, 10:45 AM
john
Guest
 
Posts: n/a
Default numeric_limits<float> questions

The code:

#include <iostream>
#include <limits>


int main()
{
using namespace std;

typedef numeric_limits<floatlimitsf;

cout<< boolalpha<< " radix= "<< limitsf::radix<< endl
<<" digits= "<< limitsf::digits<< endl
<< " digits10= "<< limitsf::digits10<< endl
<< " min()= "<< limitsf::min()<< endl
<< " max()= "<< limitsf::max()<< endl
<< " epsilon()= "<< limitsf::epsilon()<< endl
<< " min_exponent= "<< limitsf::min_exponent<< endl
<< " min_exponent10= "<< limitsf::min_exponent10<< endl
<< " max_exponent= "<< limitsf::max_exponent<< endl
<< " max_exponent10= "<< limitsf::max_exponent10<< endl
<< " is_iec559= "<< limitsf::is_iec559<< endl
<< " traps= "<< limitsf::traps<< endl;

}


in my system produces:


[john@localhost src]$ ./foobar-cpp
radix= 2
digits= 24
digits10= 6
min()= 1.17549e-38
max()= 3.40282e+38
epsilon()= 1.19209e-07
min_exponent= -125
min_exponent10= -37
max_exponent= 128
max_exponent10= 38
is_iec559= true
traps= false

[john@localhost src]$



numeric_limits<floatquestions:

Q1: min() shows up as a positive number. Why?

Q2: min() contains e-38, while min_exponent10== -37.



  #2  
Old October 31st, 2007, 11:35 AM
Duane Hebert
Guest
 
Posts: n/a
Default Re: numeric_limits<float> questions

numeric_limits<floatquestions:
Quote:
>
Q1: min() shows up as a positive number. Why?
Because min(), for floating point types, shows the
smallest positive value and not the minimum value
like integral types. Not sure why this is the case.
I would have preferred min() to work the same in all cases.
Maybe add a smallest() function to do what min() does now.

At any rate, what you probably want in -max().




  #3  
Old November 1st, 2007, 03:25 PM
Chip Coldwell
Guest
 
Posts: n/a
Default Re: numeric_limits<float> questions

john <john@no.spamwrites:
Quote:
The code:
>
#include <iostream>
#include <limits>
>
>
int main()
{
using namespace std;
>
typedef numeric_limits<floatlimitsf;
>
cout<< boolalpha<< " radix= "<< limitsf::radix<< endl
<<" digits= "<< limitsf::digits<< endl
<< " digits10= "<< limitsf::digits10<< endl
<< " min()= "<< limitsf::min()<< endl
<< " max()= "<< limitsf::max()<< endl
<< " epsilon()= "<< limitsf::epsilon()<< endl
<< " min_exponent= "<< limitsf::min_exponent<< endl
<< " min_exponent10= "<< limitsf::min_exponent10<< endl
<< " max_exponent= "<< limitsf::max_exponent<< endl
<< " max_exponent10= "<< limitsf::max_exponent10<< endl
<< " is_iec559= "<< limitsf::is_iec559<< endl
<< " traps= "<< limitsf::traps<< endl;
>
}
>
>
in my system produces:
>
>
[john@localhost src]$ ./foobar-cpp
radix= 2
digits= 24
digits10= 6
min()= 1.17549e-38
max()= 3.40282e+38
epsilon()= 1.19209e-07
min_exponent= -125
min_exponent10= -37
max_exponent= 128
max_exponent10= 38
is_iec559= true
traps= false
That looks wrong to me. I think min_exponent should be -126. On my
system, this program

#include <iostream>
#include <limits>

template <typename float_t, typename sint_t, typename uint_t, int mbits, int ebits>
class ieee_float {
#ifdef __BIG_ENDIAN__
uint_t s:1;
uint_t e:ebits;
uint_t m:mbits;
#else
uint_t m:mbits;
uint_t e:ebits;
uint_t s:1;
#endif

public:
static const uint_t mdenom = ((uint_t)1 << mbits);
static const uint_t ebias = ((uint_t)1 << (ebits - 1)) - 1;
sint_t sign(void) const { return 1 - 2*s; }
sint_t exponent(void) const { return e ? e - ebias : -(ebias - 1); }
uint_t mantissa(void) const { return ((uint_t)(!!e) << mbits) | m; }
bool infinity(void) const { return (e == ((1 << ebits) - 1)) && (m == 0); }
bool nan(void) const { return (e == ((1 << ebits) - 1)) && (m != 0); }
bool denormal(void) const { return (e == 0) && (m != 0); }
ieee_float(float_t f) { *(float_t *)this = f; }
ieee_float(uint_t u) { *(uint_t *)this = u; }
operator float_t() const { return *(float_t *)this; }
operator uint_t() const { return *(uint_t *)this; }
};

typedef ieee_float<float, int, unsigned, 23, 8single_precision;
typedef ieee_float<double, long long, unsigned long long, 52, 11double_precision;

int main(int argc, char *argv[])
{
single_precision d(std::numeric_limits<float>::min());
std::cout << "decimal: " << (float) d << std::endl;
std::cout << "hexadecimal: " << std::hex << (unsigned) d << std::dec << std::endl;
std::cout << "sign: " << d.sign() << std::endl;
std::cout << "exponent: " << d.exponent() << std::endl;
std::cout << "mantissa: " << d.mantissa() << "/" << d.mdenom << std::endl;
std::cout << "min exponent: " << std::numeric_limits<float>::min_exponent << std::endl;
return 0;
}

produced this output:

$ ./test
decimal: 1.17549e-38
hexadecimal: 800000
sign: 1
exponent: -126
mantissa: 8388608/8388608
min exponent: -125

Strange that the exponent on "std::numeric_limits<float>::min()" would
be less than "std::numeric_limits<float>::min_exponent".

Chip

--
Charles M. "Chip" Coldwell
"Turn on, log in, tune out"
Somerville, Massachusetts, New England
  #4  
Old November 1st, 2007, 07:15 PM
john
Guest
 
Posts: n/a
Default Re: numeric_limits<float> questions

Chip Coldwell wrote:
Quote:
>
That looks wrong to me. I think min_exponent should be -126. On my
system, this program
>
#include <iostream>
#include <limits>
>
template <typename float_t, typename sint_t, typename uint_t, int mbits, int ebits>
class ieee_float {
#ifdef __BIG_ENDIAN__
uint_t s:1;
uint_t e:ebits;
uint_t m:mbits;
#else
uint_t m:mbits;
uint_t e:ebits;
uint_t s:1;
#endif
>
public:
static const uint_t mdenom = ((uint_t)1 << mbits);
static const uint_t ebias = ((uint_t)1 << (ebits - 1)) - 1;
sint_t sign(void) const { return 1 - 2*s; }
sint_t exponent(void) const { return e ? e - ebias : -(ebias - 1); }
uint_t mantissa(void) const { return ((uint_t)(!!e) << mbits) | m; }
bool infinity(void) const { return (e == ((1 << ebits) - 1)) && (m == 0); }
bool nan(void) const { return (e == ((1 << ebits) - 1)) && (m != 0); }
bool denormal(void) const { return (e == 0) && (m != 0); }
ieee_float(float_t f) { *(float_t *)this = f; }
ieee_float(uint_t u) { *(uint_t *)this = u; }
operator float_t() const { return *(float_t *)this; }
operator uint_t() const { return *(uint_t *)this; }
};
>
typedef ieee_float<float, int, unsigned, 23, 8single_precision;
typedef ieee_float<double, long long, unsigned long long, 52, 11double_precision;
>
int main(int argc, char *argv[])
{
single_precision d(std::numeric_limits<float>::min());
std::cout << "decimal: " << (float) d << std::endl;
std::cout << "hexadecimal: " << std::hex << (unsigned) d << std::dec << std::endl;
std::cout << "sign: " << d.sign() << std::endl;
std::cout << "exponent: " << d.exponent() << std::endl;
std::cout << "mantissa: " << d.mantissa() << "/" << d.mdenom << std::endl;
std::cout << "min exponent: " << std::numeric_limits<float>::min_exponent << std::endl;
return 0;
}
>
produced this output:
>
$ ./test
decimal: 1.17549e-38
hexadecimal: 800000
sign: 1
exponent: -126
mantissa: 8388608/8388608
min exponent: -125
>
Strange that the exponent on "std::numeric_limits<float>::min()" would
be less than "std::numeric_limits<float>::min_exponent".
>
Chip

Your code produces in my system:


[john@localhost src]$ ./foobar-cpp
decimal: 1.17549e-38
hexadecimal: 800000
sign: 1
exponent: -126
mantissa: 8388608/8388608
min exponent: -125

[john@localhost src]$

It looks like we get the same values. My OS is CentOS 5.0, with
"gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)".

  #5  
Old November 1st, 2007, 08:35 PM
Chip Coldwell
Guest
 
Posts: n/a
Default Re: numeric_limits<float> questions

john <john@no.spamwrites:
Quote:
Chip Coldwell wrote:
Quote:
>>
>That looks wrong to me. I think min_exponent should be -126. On my
>system, this program
>>
>#include <iostream>
>#include <limits>
>>
>template <typename float_t, typename sint_t, typename uint_t, int mbits, int ebits>
>class ieee_float {
>#ifdef __BIG_ENDIAN__
> uint_t s:1;
> uint_t e:ebits;
> uint_t m:mbits;
>#else
> uint_t m:mbits;
> uint_t e:ebits;
> uint_t s:1;
>#endif
>>
>public:
> static const uint_t mdenom = ((uint_t)1 << mbits);
> static const uint_t ebias = ((uint_t)1 << (ebits - 1)) - 1;
> sint_t sign(void) const { return 1 - 2*s; }
> sint_t exponent(void) const { return e ? e - ebias : -(ebias - 1); }
> uint_t mantissa(void) const { return ((uint_t)(!!e) << mbits) | m; }
> bool infinity(void) const { return (e == ((1 << ebits) - 1)) && (m == 0); }
> bool nan(void) const { return (e == ((1 << ebits) - 1)) && (m != 0); }
> bool denormal(void) const { return (e == 0) && (m != 0); }
> ieee_float(float_t f) { *(float_t *)this = f; }
> ieee_float(uint_t u) { *(uint_t *)this = u; }
> operator float_t() const { return *(float_t *)this; }
> operator uint_t() const { return *(uint_t *)this; }
>};
>>
>typedef ieee_float<float, int, unsigned, 23, 8single_precision;
>typedef ieee_float<double, long long, unsigned long long, 52, 11double_precision;
>>
>int main(int argc, char *argv[])
>{
> single_precision d(std::numeric_limits<float>::min());
> std::cout << "decimal: " << (float) d << std::endl;
> std::cout << "hexadecimal: " << std::hex << (unsigned) d << std::dec << std::endl;
> std::cout << "sign: " << d.sign() << std::endl;
> std::cout << "exponent: " << d.exponent() << std::endl;
> std::cout << "mantissa: " << d.mantissa() << "/" << d.mdenom << std::endl;
> std::cout << "min exponent: " << std::numeric_limits<float>::min_exponent << std::endl;
> return 0;
>}
>>
>produced this output:
>>
>$ ./test
>decimal: 1.17549e-38
>hexadecimal: 800000
>sign: 1
>exponent: -126
>mantissa: 8388608/8388608
>min exponent: -125
>>
>Strange that the exponent on "std::numeric_limits<float>::min()" would
>be less than "std::numeric_limits<float>::min_exponent".
>>
>Chip
>
>
Your code produces in my system:
>
>
[john@localhost src]$ ./foobar-cpp
decimal: 1.17549e-38
hexadecimal: 800000
sign: 1
exponent: -126
mantissa: 8388608/8388608
min exponent: -125
>
[john@localhost src]$
>
It looks like we get the same values. My OS is CentOS 5.0, with
"gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)".
Well, I asked the oracle, and he quoted me chapter and verse:

Similarly ISO C++98, [lib.numeric.limits.members]/{23,24,26,27}:
static const int min_exponent;
Minimum negative integer such that radix raised to the power of one less
than that integer is a normalized floating point number.189)
Meaningful for all floating point types.
static const int max_exponent;
Maximum positive integer such that radix raised to the power one less
than that integer is a representable finite floating point number.191)
Meaningful for all floating point types.

189) Equivalent to FLT_MIN_EXP, DBL_MIN_EXP, LDBL_MIN_EXP.
191) Equivalent to FLT_MAX_EXP, DBL_MAX_EXP, LDBL_MAX_EXP.

So "min_exponent" is the minimum exponent plus one (of course!).

What I haven't been able to discover is what motivated this intuition
defying choice.

Chip

--
Charles M. "Chip" Coldwell
"Turn on, log in, tune out"
Somerville, Massachusetts, New England
 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,840 network members.