Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Floating point 浮点什么时候精确地循环?_Floating Point_Precision_Floating Accuracy - Fatal编程技术网

Floating point 浮点什么时候精确地循环?

Floating point 浮点什么时候精确地循环?,floating-point,precision,floating-accuracy,Floating Point,Precision,Floating Accuracy,我的问题被贴上了重复的标签,但它不是重复的。这个问题涉及不精确表示的情况,而我的问题是关于特殊情况下的精确表示 在Python 3会话中: >>> 0.1*3/3 0.10000000000000002 >>> 12.34567 12.34567 第一次计算会产生不精确的结果。(我确实理解原因:这是因为浮点数是四舍五入的。) 但第二次计算(从十进制分数转换为二进制FP,然后再转换回来)会产生精确的结果 我的问题是,为什么第二个结果(以及许多类似的“计算”只涉

我的问题被贴上了重复的标签,但它不是重复的。这个问题涉及不精确表示的情况,而我的问题是关于特殊情况下的精确表示

在Python 3会话中:

>>> 0.1*3/3
0.10000000000000002
>>> 12.34567
12.34567
第一次计算会产生不精确的结果。(我确实理解原因:这是因为浮点数是四舍五入的。)

但第二次计算(从十进制分数转换为二进制FP,然后再转换回来)会产生精确的结果

我的问题是,为什么第二个结果(以及许多类似的“计算”只涉及一个FP数而没有算术运算)是精确的(与Python会话中键入的结果相同)

另外:两个小数点之和(其指数相差不大)的精确性如何?

它不是“精确的”。。。12.34567没有作为二进制的精确表示64。但是Python的浮点到字符串转换默认规则产生的结果与您输入的输入相同。如果你强迫它告诉你整个故事,它将揭示不精确性:

>>> '{:.500}'.format(12.34567)
'12.3456700000000001438138497178442776203155517578125'

精确表示有两个限制

第一种方法消除了诸如12.34567和0.1之类的数字,它必须有一个有限的表示形式,即基数为2的分数。它必须等于A/B,其中A是整数,B是2的整数幂,如1、2、4、8等

这可以很容易地进行测试。首先把数字写成一个比率。例如,0.1是1/10。降到最低限度。1和10没有除1以外的公共整数因子,因此1/10已经减少。看看分母,10。它不是2的幂,因此0.1不能精确表示

现在考虑0.375。它等于375/1000或3/8。8是2的幂,因此0.375具有有限的二进制分数表示


第二组条件限制所涉及的数字的大小,以适应特定的浮点格式。

您不能做以10为基数的事情,而假定它们以相同的方式以2为基数工作

双精度IEEE

0.1 = 0x3FB999999999999A
3.0 = 0x4008000000000000
12.34567 = 0x4028B0FBA8826AA9
0.1*3.0 = 0x3FD3333333333334
(0.1*3.0)/3.0 = 0x3FB999999999999B
在计算器上更容易处理单件,请注意有趣的区别:

0.1 = 0x3DCCCCCD
3.0 = 0x40400000
12.34567 = 0x414587DD
0.1*3.0 = 0x3E99999A
(0.1*3.0)/3.0 = 0x3DCCCCCD
所以首先

0x3DCCCCCD is 0 01111011 10011001100110011001101
注意,如果分母1/3=0.3333中有一个3,则重复模式与以10为底的模式相同。比如1/60.16666667,因为我们四舍五入。好的,看过了一点,末尾应该是1001,但这太多了,如果你要切掉的点后面的数字大于一半,你就要进行四舍五入,所以0.1001在二进制中是0.101,是吗?这里也一样

在这种情况下,对于十进制数字,单精度得出正确答案,将一些数字乘以三,然后再除以,得到相同的数字,但在不同点的两倍舍入片段中,我们再次舍入,得到的数字比开始时稍微大一点

这一切都可以很容易地用十进制表示。如果我的格式是固定位数,我必须在某个点停止,因此1/6=0.166666,或者说它是0.166667。6.0就是6.00000。所以如果我使用十进制浮点格式,乘以6*(1/6),我得到0.99996或1.000002,在这两种情况下我都得不到1。不是因为四舍五入,而是因为数字不能以这种格式准确表示

如果你从一个10进制的ASCII字符串变为浮点数,然后又回到10进制的ASCII字符串,那么这就是运气。数字要么用浮点表示准确,要么不是。通过上面非常简单的以10为基数的浮点数可以看出,无论有多少个数字不到无穷大,都不会得到6*(1/6)=1,因为以10为基数的浮点数无法准确表示固定位数中的1/6

看看你的另一个号码

12.34567 = 0x414587DD
0 10000010 10001011000011111011101
12.34567 = 0x4028B0FBA8826AA9
0 10000000010 1000101100001111101110101000100000100110101010101001

1.10001011000011111011101
1.1000101100001111101110101000100000100110101010101001

很明显,single没有足够的位来表示它,并且没有进行取整,因为下一位是小于一半的零。这个双精度数字一直工作到最后,我不打算手动将它转换回10进制,但我敢打赌你一定很幸运。如果你有更多的位子,那会不会安定下来?再说一遍,我不打算为你手工转换。我认为你应该能够看到,即使你只看了0.1,然后去浮动,然后回到ASCII,你也不会得到0.1。就像在十进制中,1/6不会在那里和后面转换,如果你把它四舍五入,你会很幸运:5.9999。。。如果在正确的位置对其进行剪裁/四舍五入,则四舍五入为6.0,但这只是ASCII转换的四舍五入,而不是浮点格式表示的实际数字。

可能重复以前多次询问和回答的问题;这是浮点数学的一个普遍问题,与语言无关。你的问题对我来说没有意义。您所说的从小数点切换到二进制浮点并返回是什么意思?你的第一次十进制乘法失去了准确性。大部分可能的重复回答了标题,但不是这样:“我的问题是为什么第二个结果是精确的(与Python会话中键入的结果相同)?”@JohnKugelman无法解释为什么第二个结果是精确的,因为它不是。正如前面的答案所指出的,默认的浮点到字符串转换精度隐藏了不精确性。这应该在你的答案中。@JohnKugelman为什么?关于一个任意例子是准确的错误假设已经得到处理。我不是要发表关于如何确定准确性的更广泛的问题,就是根本不发表。仅仅重复前面的答案是没有意义的。是的,这个话题已经讨论过无数次了,链接的问题很可能是重复的…或者这是重复的。浮点什么时候轮到?在尾数的最后一个数字和尾数前尾数末端的粘性部分之间,我