浮点处理器非确定性?

Pan*_*sis 5 c++ python floating-point

在没有得到不必要的细节的情况下,基于相同的输入,浮点数(x86_64)上的操作是否可能返回结果的小变化?甚至一点点不同?

我正在模拟一个基本上混乱的系统,我希望数据上的小变化具有可见效果.但是我希望,使用相同的数据,程序的行为将得到修复.不是这种情况.我对程序的每次运行都有可见但可接受的差异.

我想我已经在某个地方留下了一些未初始化的变量......

我使用的语言是C++和Python.

回答

拉塞尔的回答是正确的.浮点运算是确定性的.非决定论是由悬空指针引起的.

Tho*_*mas 5

是的,这是可能的.引用C++ FAQ:

事实证明,在某些安装中,即使x == y,cos(x)!= cos(y).那不是拼写错误; 如果你没有感到震惊,那就再读一遍:某些东西的余弦可能与同一个东西的余弦不相等.(或正弦,或切线,或日志,或任何其他浮点计算.)

为什么?

[F]浮点计算和比较通常由通常包含特殊寄存器的特殊硬件执行,并且这些寄存器通常具有比双精度更多的位.这意味着中间浮点计算通常具有比sizeof(double)更多的位,并且当浮点值写入RAM时,它经常被截断,通常会丢失一些精度.

  • 但这不是非决定论.相同代码中的相同输入应该给出相同的结果.你在这里给出的解释允许两个表面上相似的代码块从相同的输入产生两个不同的结果,但这完全是另一回事. (7认同)
  • @Thomas:上下文切换不会更改寄存器,因为进程可见.操作系统保存并恢复体系结构指定的编程环境的所有状态,包括所有常规寄存器的所有位.(一些特殊的东西可能会改变,例如加载和保留和存储条件指令的锁定状态.)考虑到这些"额外"位在C语言中未指定,但它们绝对是编程环境的一部分.汇编语言程序员,必须由操作系统保存. (5认同)

Rus*_*ove 4

与托马斯的回答相反,浮点运算不是不确定的。它们非常微妙,但是如果给定的程序不使用未初始化的内存或故意随机化的数据,则它应该为相同的输入提供相同的输出。

我的第一个问题是,“相同的数据”是什么意思?这些数据是如何进入你的程序的?