|
|
1
16
我怀疑差异是从80位浮点值到长浮点值的转换,而不是从80位浮点值到64位浮点值的转换,以及 然后 向长型转变。 (80位出现的原因是,这是实际算术使用的典型精度,以及浮点寄存器的宽度。) 假设80位的结果类似于10.99999999999999—从该结果到长结果的转换为10。然而,与80位值最接近的64位浮点值实际上是11.0,因此两级转换最终得到11。 编辑:为了增加重量… 这里有一个Java程序,它使用任意精确的算术来进行同样的计算。请注意,它将最接近0.1的双精度值转换为BigDecimal-该值为0.10000000000000055511151231257827021181583404541015625。(换句话说,计算的确切结果是 不 11,不管怎样)
结果如下:
换句话说,这是正确的约40位十进制数字(远远超过64位或80位浮点可以处理)。 现在,让我们考虑一下这个数字在二进制中是什么样子的。我没有任何工具可以轻松地进行转换,但我们可以再次使用Java来帮助。假设一个标准化的数字,“10”部分最终使用三个位(比11=1011少一个)。剩下60位尾数表示扩展精度(80位),48位表示双精度(64位)。 那么,每个精度中最接近11的数字是什么?再次,让我们使用Java:
结果:
所以,我们得到的三个数字是:
现在为每个精度计算出最接近正确值的值-对于扩展精度,它小于11。将这些值四舍五入为一个长整数,结果分别为10和11。 希望这是足以说服怀疑者的证据;) |
|
|
2
2
我的32位x86 Linux系统运行gcc 4.3.2也得到了10&11。 相关的C/ASM如下:
答案留给感兴趣的读者作为练习。 |
|
|
3
1
codepad.org(gcc 4.1.2)反转示例的结果,而在我的本地系统(gcc 4.3.2)中,这两种情况下我都得到了11。这对我来说意味着这是一个浮点问题。或者,理论上可以是截断(b-a+c),在整数上下文中,它的值为(2-1+0)/.1,即10,而在浮点上下文(2.0-1.0+0.1)/.1=1.1/.1=11。不过那会很奇怪。 |
|
|
4
0
在Linux上直接复制/粘贴和编译给了我11个。添加
|
|
|
5
0
Here is a bunch of detail on floating point issues and a really good article. 但基本上,并不是所有的浮点值都可以用一定数量的位(32位或64位或其他)来表示。这是一个深奥的主题,但我喜欢它,因为它让我想起 Prof. Kahan . :) |
|
|
MaPo · Linux,设置锁定ICMP_过滤器选项 1 年前 |
|
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 1 年前 |
|
|
Bobby · 复合字面值总是左值吗? 1 年前 |
|
9-Pin · C: 嵌套结构的堆栈内存分配 1 年前 |