Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are FLT_DIG, DBL_DIG, and LDBL_DIG determined in C [duplicate]

FLT_DIG, DBL_DIG, LDBL_DIG are the number of decimal digits that can be accurately represented by float, double, and long double types respectively.

#include <stdio.h>
#include <float.h>

int main(void)
{
  printf("%d, %d, %d\n", FLT_DIG, DBL_DIG, LDBL_DIG);
  return 0;
}

prints 6, 15, and 18. The standard, at section 5.2.4.2.2, gives the accurate formula -- e.g. for float, p = 24, and b = 2:

enter image description here

But I'm not clear how the above formula (the "otherwise") is derived. Can someone please explain?

The below is the reasoning I followed which does not answer the question. Consider type float which has 23 bits in the significand (IEEE-754 standard). The maximum binary integer that can be accurately represented is:

  100...00 (25 digits total, because we have an implicit 1)
  = 2^24
  = 10^(24*log(2)) 

Hence # decimal digits:

= floor(24*log(2)) = 7

And not floor(23 * log(2)) = 6 as the standard states.

like image 994
cmutex Avatar asked Nov 30 '19 21:11

cmutex


1 Answers

How are FLT_DIG, DBL_DIG, and LDBL_DIG determined (?)

Roughly, with p binary digits, p*(log102) decimal digits can be encoded. Every binary digit contributes to about .3 decimal digits.

Recall floating point values and numbers as decimal text with n signification digits and an exponent are distributed linearly within a larger logarithmic distribution.

The -1 of below comes from worst case alignments issues where the distribution of decimal values is densest relative to the binary values. There is no -1 if the float base was 10, as the distribution aligns.

enter image description here

The below is the reasoning I followed which does not answer the question. ...

OP's line of reasoning fails per #6 in here. The alignment of decimal values to binary ones does not always "work".

A float as binary32 example.

  1. In the range [233 or 8,589,934,592 ... 234 or 17,179,869,184), again, 223 (8,388,608) values are linearly encoded: 1024.0 apart from each other. In the sub range [9,000,000,000 and 10,000,000,000), there are about 976,562 different values.

  2. As text, the range [9,000,000*103 and 10,000,000*103), using 1 lead digit and 6 trailings ones, there are 1,000,000 different values. Per #1, In the same range, there are less than 1,000,000 different float values. Thus some decimal textual values will convert to the same float. In this range we can use 6, not 7, digits for distinctive conversions.

like image 75
chux - Reinstate Monica Avatar answered Nov 10 '22 23:11

chux - Reinstate Monica