This question was posed by Mr. Anonymous:
Here are some examples to demonstrate the question.
Let’s take a value 1.2345678901234567e+04 (17 significant digits) and get its decimal representation in:
- C 8-byte
double
floating-point value (formatted as “%.25e” with gcc printf
),
- C
long double
floating-point value (formatted as “%.25Le” with gcc printf
),
- as displayed by SQLite
printf
with “alternate-form-2” format “%!.25e”:
SQLite version 3.41.0 2023-02-21 18:09:37
sqlite> select printf(‘%!.25e’, 1.2345678901234567e+04);
1.2345678901234567092972532e+04
Here are all of the representations together:
value: 1.2345678901234567000000000e+04
C “%.25e”: 1.2345678901234567092615180e+04 (double)
“%!.25e”: 1.2345678901234567092972532e+04 (SQLite)
C “%.25Le”: 1.2345678901234567000244624e+04 (long double)
As one can see, all of the representations retain at least 16 significant figures, as expected in this case for a double
.
However, looking beyond the 16 figures, there is some divergence in the displayed values. I understand that these “extra” digits are not random and are due to the IEEE 754 floating-point resolution, in other words, that’s how the real value maps onto available floating-point value. long double
offers a higher resolution, so to speak and is the closest to the real value.
SQLite, as I understand, supports only the double
. Yet the SQLite’s printed value shows some other version of the “extended” digits. Thus my question about the meaningfulness of these digits. They don’t match either double
or long double
, though closer to double
in this case. Does this extended format mean to match the 'double'
representation?
The response from someone else was:
You can “run the conversion” process to any number of output digits your little heart desires. SQLite3, and various other implementations for converting IEEE-754 floating point values to text, have chosen “arbitrary limits” for how long to “loop around the algorithm” which produces output digits.
Whether these “output digits” have any meaning whatsoever is to be determined by the user of the output. Just because you ask for 5.2f output formatting does not mean that the value is between 99.99 and -9.99 and that the rest of the significant digits are zero. Nor does requesting the format .26e mean that the value contains 26 significant digits.
If other words, just because you asked the question:
for i in range(4000):
digit = int(value / 10)
print(digit,end='')
value = (value - digit*10)/10
print()
does not mean that the 4000 digits thus printed have any meaning whatsoever.
An IEEE-754 binary64 floating point number contains about 15.95 decimal digits of accuracy. This means that any 17 digit represenation is sufficient to express the value approximated and to “trip it” though properly functioning input/output routines.