简体   繁体   English

打印双精度浮点数

[英]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 我正在尝试在字符串中表示双精度,为此,我正在使用grisu的算法,您可以在此处查看: 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: 我已经做完了,并且显然可以正常工作,当我与高精度的printf输出进行比较时,我的问题来了,就像这样:

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

Outputs 输出

0.3333333333333333148296162562473909929394721984863281250000000000000000000000000000000000000000000000

With grisu's algorithm i can obtain the following: 使用grisu的算法,我可以获得以下信息:

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). 这是逻辑,因为您可以在“ 5.3 C实施”(第6页)的PDF中读取,双精度的最高精度为21位。 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? 然后,如果我的最大精度是多少,或者哪种算法正在使用printf来获得这种精度,那么我如何获得余数?

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. 浮点算术的基本原理(特别是在IEEE 754标准中指定)是,浮点数据正好表示一个特定的数字。

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. 在您的示例中,将一分为三将得到一个精确为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. 带有转换说明符%.100f printf调用要求将此二进制浮点值转换为十进制。 That is a mathematical operation, and the mathematical result of converting the binary floating-point value to decimal would be “0.333333333333333314829616256247390992939472198486328125”. 那是数学运算,并且将二进制浮点值转换为十进制的数学结果将是“ 0.333333333333333314829616256247390992939472198486328125”。 Since you told printf to use 100 digits, it has enough digits to produce the exact result, so it does. 因为您告诉printf使用100位数字,所以它有足够的数字来产生准确的结果,所以它确实如此。

(This suggests that you are using a good-quality printf implementation. Some implementations do not perform this operation correctly.) (这表明您使用的是高质量的printf实现。某些实现无法正确执行此操作。)

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. 您引用的Florian Loitsch的论文提供了将二进制浮点值转换为足够的十进制数字的算法,以使该值与相邻的浮点值区分开。 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. 例如,在具有两位数字的base-3浮点数中,我们可以表示数字0、1 / 9、2 / 9、3 / 9、4 / 9,依此类推。 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. 在这种情况下,如果值是4/9(.4444…),则打印“ .4”就足以将值与.3333…和.5555…区别开来,但不能完全代表该值。 Loitsch's algorithms only produce enough digits to distinguish values, not usually enough to show the exact mathematical value. Loitsch的算法仅产生足够的数字来区分值,通常不足以显示确切的数学值。

(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.) (Loitsch的论文还讨论了算法多久产生一次最短的结果来区分该值-足够多的数字就可以完成工作,而没有更多。)

The classic paper on converting between bases is Correctly Rounded Binary-Decimal and Decimal-Binary Conversions by David M. Gay. 关于基数之间转换的经典论文是David M. Gay 撰写的“正确舍入的二进制十进制和十进制二进制转换”

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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