【问题标题】:Are all C++ fixed-point operations deterministic?所有 C++ 定点操作都是确定性的吗?
【发布时间】:2015-05-05 14:48:42
【问题描述】:

我正在用 C++ 编写一个小型 RTS 引擎,并想使用锁步同步。

由于浮点确定性是我什至无法实现的,所以我必须使用定点数学。

在无符号整数上定义的典型操作的确定性如何(通过不同的编译器和 CPU)?

我对除法特别感兴趣,因为它会导致四舍五入。

【问题讨论】:

  • 100% 确定性,或者至少应该是,如果不是,CPU 可能会损坏
  • @zoran404 当然,双精度可以存储它,但是如果您对其进行数学运算,编译器不一定能确保 100% 可移植的结果。例如,它可能使用 x87 的 80 位扩展精度,因此会给出不同的结果。或者它可能会进行非法的操作重新关联,a + (b + c) == (a + b) + c 不一定是真的,但一些编译器会假装他们可以做到这一点(ICC 默认情况下,如果您使用显然不安全的不安全数学,则为 GCC)
  • 这个问题没有意义,如果使用IEEE浮点,结果也是确定性的。错误总是一样的。你到底在担心什么?那个浮点数不够精确?另外我不明白锁步与浮点与定点有什么关系......
  • 更不用说,如果您正在开发游戏,则会出现一些有用的行为,例如 DirectX 会默默地改变您的 CPU 舍入模式。

标签: c++ fixed-point


【解决方案1】:

基本整数类型的大小在不同平台上有所不同。您可以通过使用uint32_t 和类似类型来避免此问题。

有符号整数溢出是未定义的行为,尽管溢出对于无符号整数类型是明确定义的(您可以进行算术模2^N)。即使如此,您也必须小心,因为模运算通常不是您想要做的。

我相信曾几何时的标准是开放的,确切地说是如何四舍五入(尽管我不确定“正/正”是否曾经开放)。但我认为现在这是标准化的,即使没有,向 0 舍入也几乎是通用的。

但是你可以使用numeric_limits来检查。如果相信this documentation,该标准确实保证向零舍入。

【讨论】:

  • 在 C++03 中,除法舍入是开放的。在 C++11 中,它现在已经标准化,我认为是可配置的,但我不确定。
猜你喜欢
  • 2014-08-11
  • 2023-03-20
  • 2013-02-07
  • 1970-01-01
  • 2021-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
相关资源
最近更新 更多