简体   繁体   中英

printing double precision floating point numbers

I'm trying to represent a double in a string, for this purpose i'm using grisu's algorithm, you can check it out here: https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf

i'm done with it, and apparently is working, my question comes when comparing with printf output with big precision, something like that:

double u = 1, t = 3;
double co = u/t;
printf("%.100f", co);

Outputs

0.3333333333333333148296162562473909929394721984863281250000000000000000000000000000000000000000000000

With grisu's algorithm i can obtain the following:

3333333333333333e-16

What is logic because the max precision you can get with double is 21 digits as you can read in the PDF at "5.3 C Implementation" (page 6). Then how can i obtain the rest if my max precision is this, or which algorithm is using printf to get this amount of precision?

A fundamental principle of floating-point arithmetic, particularly as specified in the IEEE 754 standard, is that a floating-point datum represents exactly one specific number.

When performing an operation on floating-point numbers, the exact mathematical result might not be representable in the floating-point format. In this case, the operation returns the nearest representable number according to some rule (often round to nearest with ties to even digit, but sometimes round toward +infinity, round toward -infinity, round toward zero, or round to odd digit). Thus, operations in floating-point arithmetic may return approximate results, but numbers are exact.

In your example, dividing one by three results in a floating-point number that is exactly 0.333333333333333314829616256247390992939472198486328125. This is because the mathematical result is exactly ⅓, but that is not representable in binary floating-point, and the number shown above is the closest value that is representable, so that is the result.

The call to printf with the conversion specifier %.100f requests that this binary floating-point value be converted to decimal. That is a mathematical operation, and the mathematical result of converting the binary floating-point value to decimal would be “0.333333333333333314829616256247390992939472198486328125”. Since you told printf to use 100 digits, it has enough digits to produce the exact result, so it does.

(This suggests that you are using a good-quality printf implementation. Some implementations do not perform this operation correctly.)

The paper by Florian Loitsch you cite provides algorithms for converting binary floating-point values to enough decimal digits that the value is distinguished from neighboring floating-point values. It does not usually generate enough decimal digits to show the exact value. For example, in base-3 floating-point with two digits, we could represent the numbers 0, 1/9, 2/9, 3/9, 4/9, and so on. In this case, if the value is 4/9 (.4444…), then printing “.4” would be enough to distinguish the value from .3333… and .5555…, but it would not exactly represent the value. Loitsch's algorithms only produce enough digits to distinguish values, not usually enough to show the exact mathematical value.

(Loitsch's paper also discusses how often the algorithms produce the shortest result that distinguishes the value—just enough digits to do the job and no more.)

The classic paper on converting between bases is Correctly Rounded Binary-Decimal and Decimal-Binary Conversions by David M. Gay.

[f] printf的输出是错误的精度,在某种意义上,它告诉您以十进制表示时二进制数的精确值,就像该二进制数末尾具有无限个0位一样,我们知道该数字可能首先以十进制开头。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM