【问题标题】:C++ Floating point differenceC++ 浮点数差
【发布时间】:2020-01-14 08:55:55
【问题描述】:

我试图在 2 个不同的平台上获得完全相同的结果,即 Solaris 和 Linux(sun-studio vs GCC)。整个代码使用双数据类型。但是当我打印输出时,我会看到浮点数的差异(比如小数点后 20 位)。

我需要知道的是我是否可以设置一些编译器标志以使 GCC 和 sun-studio 编译器的行为相同。附图显示了 Double 数据类型的差异。左侧是 GCC 的输出,另一个是 sun-studio。

【问题讨论】:

  • 没有这样的标志,除了学会忍受它,你无能为力。
  • 如果您对此感到担忧,您可能遇到了设计问题。
  • 您不能强制两个编译器生成相同的代码,因为它们是不同的产品。但是,您可以改用long double 来提高准确性。
  • 另外,这不仅受编译器影响,还受操作系统和硬件影响。
  • 也许你得到相同的结果,但打印方法不同。您打印的数字比 double 数据类型通常具有的有效数字多,因此打印例程可能会与打印额外数字的方式不同。如果两个平台都使用 IEEE754,而您只使用基本操作(+、-、*、/、sqrt),那么您应该得到相同的结果。如果你使用其他操作,有一些开源库可以用基本操作计算其他操作,这样你就可以让你的程序跨平台保持一致。

标签: c++ gcc


【解决方案1】:

主要问题来自于此:

我试图在 2 个不同的平台上获得完全相同的结果

您不能保证在两个不同的平台上获得相同的结果。他们在如何实现浮动操作方面可能有很多不同。

您的问题的一个解决方案:定点算术。

另外,看看这些答案:

Cross Platform Floating Point Consistency

Are IEEE float and double guaranteed to be the same size on any OS?

它们是您了解正在发生的事情的一个很好的开始。

【讨论】:

  • 此外,如果您更改(名义上可交换)操作的顺序等,您甚至不能保证在 same 平台上获得相同的结果。
  • @Useless:另一方面,如果一个平台使用 IEEE-754(今天很常见),则可以保证 +、-、*、/(这些也是可交换的)和 sqrt 的一致性.
  • @geza -- 在编译器遵循规则的范围内保证一致性。大多数编译器默认遵循规则,以生成运行速度更快的代码。他们将有一个命令行开关来开启完全一致性。
  • @PeteBecker:gcc、clang、msvc 和 icc 默认遵循规则。您指的是哪些编译器?
  • @geza -- 好吧,所有这些。 也许事情与几年前有所不同。最被忽略的 IEEE 要求是存储计算值将其类型缩小到存储值的类型。这种缩小可能会很昂贵(参见 Java 灾难性的“严格” fp),并且当存储只是到一个中间变量并且该变量的值用于后续计算时,编译器会忽略存储并继续在完全内部精度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
  • 2013-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多