14

I have read recommendations to use the "FLT_MIN" and "FLT_MAX" values for float. Whenever I do this, codeblocks tells me its

max: 3.40282e+038 min: 1.17549e-038

Not knowing what this meant I tried to get real values and got

max: 47.2498237715 min: -34.8045265148

... but these don't clarify things.

Here is a snippet from my code

   char c;         // reserve: 1 byte, store 1 character (-128 to 127)
   int i;          // reserve: 4 bytes, store -2147483648 to 2147483657
   short int s;    // reserve: 2 bytes, store -32768 to 32767
   float f;        // reserve: 4 bytes, store ?? - ?? (? digits)
   double d;       // reserve: 8 bytes, store ?? - ?? (? digits)
   unsigned int u; //reserve: r bytes store 0 to 4294967295

   c = 'c';
   cout << c <<" lives at " << &c <<endl;

   i = 40000;
   cout << i <<" lives at " << &i <<endl;

   s = 100;
   cout << s <<" lives at " << &s <<endl;

   f = 10.1;
   cout << f <<" lives at " << &f <<endl;

   d = 10.102;
   cout << d <<" lives at " << &d <<endl;

   u = 1723;
   cout << u <<" lives at " << &u <<endl;

In the snippet we can clearly see the min-max values of a short int for example at -32768 - 32767. These are proper understandable values, but for float and int, the real values are not clear.

belwood
  • 3,320
  • 11
  • 38
  • 45
user9318444
  • 431
  • 1
  • 5
  • 9
  • 3
    http://en.cppreference.com/w/cpp/types/numeric_limits – Borgleader Feb 05 '18 at 19:33
  • 1
    http://en.cppreference.com/w/cpp/types/numeric_limits –  Feb 05 '18 at 19:33
  • @Borgleader 10s ninja :-D But I'm an ole man ya know ;-) –  Feb 05 '18 at 19:34
  • 2
    One question per question please. See [ask]. – Paul R Feb 05 '18 at 19:35
  • 1
    i dont understand the question. its like asking "what is the meaning of 42?". The numbers you get are the min/max as returned from FLT_MIN/MAX... – 463035818_is_not_an_ai Feb 05 '18 at 19:37
  • If you want to remove the scientific notation, use the [`std::fixed`](http://en.cppreference.com/w/cpp/io/manip/fixed) manipulator to see the value in normal notation. – Arnav Borborah Feb 05 '18 at 19:44
  • I reopened this since it was incorrectly marked as a duplicate of a question which does not address how to get the minimums. Particularly for floating point, getting the minimums is different from getting the maximums since distinctions are made for least magnitude normal value, least positive value, least finite value, and least value, all of which are different in IEEE 754. – Eric Postpischil Feb 05 '18 at 20:18
  • 1
    Nonetheless, the question should be split, separating the numeric limits questions from the address questions. – Eric Postpischil Feb 05 '18 at 20:23

4 Answers4

26

Alright. Using what I learned from here (thanks everyone) and the other parts of the web I wrote a neat little summary of the two just in case I run into another issue like this.

In C++ there are two ways to represent/store decimal values.

Floats and Doubles

A float can store values from:

  • -340282346638528859811704183484516925440.0000000000000000 Float lowest
  • 340282346638528859811704183484516925440.0000000000000000 Float max

A double can store values from:

  • -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0000000000000000 Double lowest

  • 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0000000000000000 Double max

Float's precision allows it to store a value of up to 9 digits (7 real digits, +2 from decimal to binary conversion)

Double, like the name suggests can store twice as much precision as a float. It can store up to 17 digits. (15 real digits, +2 from decimal to binary conversion)

e.g.

     float x = 1.426;
     double y = 8.739437;

Decimals & Math

Due to a float being able to carry 7 real decimals, and a double being able to carry 15 real decimals, to print them out when performing calculations a proper method must be used.

e.g

include

typedef std::numeric_limits<double> dbl; 
cout.precision(dbl::max_digits10-2); // sets the precision to the *proper* amount of digits.
cout << dbl::max_digits10 <<endl; // prints 17.
double x = 12345678.312; 
double a = 12345678.244; 
// these calculations won't perform correctly be printed correctly without setting the precision.


cout << endl << x+a <<endl;

example 2:

typedef std::numeric_limits< float> flt;
cout.precision(flt::max_digits10-2);
cout << flt::max_digits10 <<endl;
float x =  54.122111;
float a =  11.323111;

cout << endl << x+a <<endl; /* without setting precison this outputs a different value, as well as making sure we're *limited* to 7 digits. If we were to enter another digit before the decimal point, the digits on the right would be one less, as there can only be 7. Doubles work in the same way */

Roughly how accurate is this description? Can it be used as a standard when confused?

ljden
  • 352
  • 1
  • 11
user9318444
  • 431
  • 1
  • 5
  • 9
  • 1
    "store a value of up to 9 digits (7 real digits, +2 from decimal to binary conversion)" More likely should be "9 digits (6 real digits, +3 from ...` – chux - Reinstate Monica Jul 07 '20 at 16:28
  • 1
    `Float's precision allows it to store a value of up to 9 digits`, but the number you wrote just before that contains like 40 digits..? – Sti Feb 14 '22 at 08:36
  • This is the wrong formulation. With the first 9 digits all the ones following after are already completely determined. But you can not store faithfully any 9 digits number in a `float`. That claim only holds with 6 digits. – Lutz Lehmann May 17 '23 at 10:59
12

The std::numerics_limits class in the <limits> header provides information about the characteristics of numeric types.

For a floating-point type T, here are the greatest and least values representable in the type, in various senses of “greatest” and “least.” I also include the values for the common IEEE 754 64-bit binary type, which is called double in this answer. These are in decreasing order:

  • std::numeric_limits<T>::infinity() is the largest representable value, if T supports infinity. It is, of course, infinity. Whether the type T supports infinity is indicated by std::numeric_limits<T>::has_infinity.

  • std::numeric_limits<T>::max() is the largest finite value. For double, this is 21024−2971, approximately 1.79769•10308.

  • std::numeric_limits<T>::min() is the smallest positive normal value. Floating-point formats often have an interval where the exponent cannot get any smaller, but the significand (fraction portion of the number) is allowed to get smaller until it reaches zero. This comes at the expense of precision but has some desirable mathematical-computing properties. min() is the point where this precision loss starts. For double, this is 2−1022, approximately 2.22507•10−308.

  • std::numeric_limits<T>::denorm_min() is the smallest positive value. In types which have subnormal values, it is subnormal. Otherwise, it equals std::numeric_limits<T>::min(). For double, this is 2−1074, approximately 4.94066•10−324.

  • std::numeric_limits<T>::lowest() is the least finite value. It is usually a negative number large in magnitude. For double, this is −(21024−2971), approximately −1.79769•10308.

  • If std::numeric_limits<T>::has_infinity and std::numeric_limits<T>::is_signed are true, then -std::numeric_limits<T>::infinity() is the least value. It is, of course, negative infinity.

Another characteristic you may be interested in is:

  • std::numeric_limits<T>::digits10 is the greatest number of decimal digits such that converting any decimal number with that many digits to T and then converting back to the same number of decimal digits will yield the original number. For double, this is 15.
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 2
    why theres no a short answer to this? the max and the min value of a float storage? – vincent thorpe Feb 09 '20 at 02:03
  • My short answer: for max value of floating point, use `std::numeric_limits::infinity()`. For min value, use `-std::numeric_limits::infinity()`. All others limits (`min`, `max`, `lowest`, `denorm_min`) are for very specific and advances usages. I never used them. – prapin Mar 28 '23 at 08:57
8

It's all to be found in numeric_limits.

But BEWARE

For some reason unknown to me, std::numeric_limits<float>:min() does not return the minimum float. Instead it returns the smallest positive float that is represented in normalized form. To get the minimum, use std::numeric_limits<float>::lowest(). I kid you not. Likewise for other floating point types, i.e. double and long double.

http://en.cppreference.com/w/cpp/types/numeric_limits

Jive Dadson
  • 16,680
  • 9
  • 52
  • 65
0

In C++ you can use the std::numeric_limits class to get this sort of information.

If has_infinity is true (which it will for basically any platform nowadays), then you can use infinity to get the value which is greater than or equal to all other values (except NaNs). Its negation will give a negative infinity, and be less than or equal to all other values (except NaNs again).

If you want finite values, then you can use max, which will be greater than or equal to all other finite values, and lowest, which is less then or equal to all other finite values.

Somewhat confusingly, min actually gives you the smallest positive normalized value, which is completely out of sync with what it gives with integer types (thanks @JiveDadson for pointing this out).

Simon Byrne
  • 7,694
  • 1
  • 26
  • 50
  • 1
    I dont fully understand. Using FLT_MANT_DIG (how many digits can we store in a float) you get 24, however its not possible to store this many digits. Also, if float and doubles are infinite, does this mean we can store as large values as we want inside floats? and using std::numeric_limits::min() returns 0.000000 - this dosen;t make sense – user9318444 Feb 05 '18 at 20:27
  • It refers to the number of digits in the formats radix, which in this case is 2. (i.e. there are 24 bits in the significand of a binary32 number) – Simon Byrne Feb 05 '18 at 21:17
  • 1
    Regrettably, `std::numeric_limits::min()' does not mean what you think it does for floating point T. I even caught the STL of VC++ misusing it. – Jive Dadson Feb 05 '18 at 21:27
  • So how do i found out how many digits in a float/double? and the max/min value one can store inside one? – user9318444 Feb 05 '18 at 21:49
  • Thanks @JiveDadson! I completely forgot about that messed up behaviour. – Simon Byrne Feb 05 '18 at 22:04
  • @user9318444 For decimal digits, you want [`digits10`](http://en.cppreference.com/w/cpp/types/numeric_limits/digits10) – Simon Byrne Feb 05 '18 at 22:05