0

DBL_MAX is

179769313486231570814527423731704356798070567525844996598917476803157260
780028538760589558632766878171540458953514382464234321326889464182768467
546703537516986049910576551282076245490090389328944075868508455133942304
583236903222948165808559332123348274797826204144723168738177180919299881
250404026184124858368.000000

But if I do:

double a=1234567890123456789.0;
printf("%f",a);

1234567890123456768.000000

Here the precision is 17 digits.

double a=0.1234567890123456789;
printf("%.20f",a);

0.1234567890123456773

Here also the precision after the floating point is 17 digits:

double a=1234567890.1234567890123456789;
printf("%.20f",a);

That will generate:

1234567890.12345671653747558594

Now, the precision will be 10 digits for decimal + 7 after the floating point which makes 17.

Does that mean that I have only 17 digits to get a precise value for double? If yes, why is the number of digits of DBL_MAX over 300 digits?

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • in the standard. `DBL_MAX 1E+37` is the minimum requirement. And for the typical IEC 60559 floating point, it is `DBL_MAX 1.7976931348623157E+308`. Not sure where you got thatvalue, but there always should be some exponential representation for these values. If you got this from some website: Ask them, not us! – too honest for this site Jul 28 '16 at 16:10
  • The problem the system cannot talk :/. Anyway what about the precision ? – rondino robert Jul 28 '16 at 16:11
  • How about reading the standard yourself? You don't expect us to paste what the standard says, just to correct some obscure value we don't even know where you got them from, don't you? – too honest for this site Jul 28 '16 at 16:12
  • If you don't mind giving me some of your time I will keep it on reading the standard and many things ! – rondino robert Jul 28 '16 at 16:15
  • Where does this weird value come from? Who said that DBL_MAX has ~300 digits precision? – Jean-Baptiste Yunès Jul 28 '16 at 16:17
  • okay guys don't say something I did not say. The value you can generate it by a code as DBL_MAX is a n float.h – rondino robert Jul 28 '16 at 16:23
  • I don't care too much about the value of DBL_MAX more than the precision ! – rondino robert Jul 28 '16 at 16:23
  • 2
    The representation of numbers is *not decimal*, so it is pretty meaningless to define the precision in terms of decimal numbers, as it will change depending on the number itself. – Eugene Sh. Jul 28 '16 at 16:32
  • Maybe I did not explain it very well but surely you got the point try to minimize the decimal part (left part from the floating point) and the precision will be added to the right part. – rondino robert Jul 28 '16 at 16:38
  • 1
    Well, that's simplistic. @chux has a good answer (as usual). – Eugene Sh. Jul 28 '16 at 16:40
  • If it is simplistic and a good answer why you did not upvote it then ?! @EugeneSh. – rondino robert Jul 28 '16 at 16:43
  • 3
    First of all - I did. Second - simplistic was about your view, not the answer. Third - don't tell people what to do with their votes. – Eugene Sh. Jul 28 '16 at 16:45

2 Answers2

2

Typical double has 15-16 decimal digits of significance - as compared to the next double.

All finite double have exact values like with OP's DBL_MAX = 1797693134862315708.... Floating point numbers are distributed logarithmically. So typically there are as many different double between 0.5 and 1.0 as there are between 2 and 4.

This distribution means OP's 2nd largest number only matches DBL_MAX to first 16 places out of the 300+ digits. See below.


Does it mean that I have only 17 digits to get a precise value for double ? If yes what is the use of all that number of digits for DBL_MAX more than 300 digit?

double, as binary64 can represent exactly about 2**64 different numbers. 0.1234567890123456789 is not one of them. The closest double is 0.1234567890123456773... Notice it matches to at least 15 (DBL_DIG) digits.

Usually this means the exact value of a double is not as important as its relative difference to the next double.

The value of 1e300 or 1e-300 is one of range, not precision.


int main(void) {
  printf("%.*e\n", DBL_DECIMAL_DIG + 2, DBL_MAX);
  printf("%.*e\n", DBL_DECIMAL_DIG + 2, nextafter(DBL_MAX,0));
  printf("%.*e\n", DBL_DECIMAL_DIG + 2, nextafter(0, 1));
}

Output

1.7976931348623157081e+308
1.7976931348623155086e+308
4.9406564584124654418e-324

Consider using printf("%.*e", DBL_DECIMAL_DIG-1, a); rather than printf("%.20f",a); to get a more clear view of the decimal notation significance of a double. If you are ready for hexadecimal notation, try printf("%a",a);

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 1
    [You get 15-16 decimal digits](http://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/) – Rick Regan Jul 28 '16 at 18:30
  • @Rick Regan Yes, I'll go with 15-16. It depends on the region of FP numbers. 17 is the number of significant digits needed with binary64 to distinctly print all of them. – chux - Reinstate Monica Jul 28 '16 at 18:44
2

The commonest system for representing C doubles is IEEE 754 64-bit binary floating point. It is a base 2 system. That means the exactly representable numbers have relatively short binary representations - fitting in 64 bits - but not necessarily short decimal representations.

The exact value of the largest finite number is 2^1024 - 2^971 or 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368

That is not very useful information, because of the granularity of the numbers. Consecutive numbers differ by about one part in 10^16.9. For example, the next to largest representable number is 179769313486231550856124328384506240234343437157459335924404872448581845754556114388470639943126220321960804027157371570809852884964511743044087662767600909594331927728237078876188760579532563768698654064825262115771015791463983014857704008123419459386245141723703148097529108423358883457665451722744025579520

You don't need all those digits to distinguish them. If you know you have one of those numbers, seeing the 17 character prefixes 17976931348623157 and 17976931348623155 is enough to tell which.

Library functions that convert double to decimal strings have a problem. How many digits should you print? Here are some of the options:

  • Print the exact value. Almost always the wrong thing to do, because you will print a lot of digits that do not convey any useful information.
  • Print enough digits to distinguish which double you started with. That is the choice made, for example, for Java's Double.toString. This allows exact recovery of the double from the printed value.
  • Print only a fixed number of digits. Makes for tidy reports.
Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • [I used to think Java's Double.toString worked that way too](http://www.exploringbinary.com/java-doesnt-print-the-shortest-strings-that-round-trip/). For example, try printing 8.41E21. – Rick Regan Jul 28 '16 at 18:22
  • @RickRegan So far, I have not encountered a situation in which Double.toString fails to produce enough digits to distinguish the exact value. Your example is a case of it outputting more digits than the shortest possible. – Patricia Shanahan Jul 28 '16 at 19:30
  • I was interpreting what you wrote as "Print JUST enough digits". Printing "enough" digits is kind of open-ended though, since that means it can print anything from the shortest to the exact value. – Rick Regan Jul 29 '16 at 15:38