如何使SUN上的gcc以与Linux中相同的方式计算浮点
我有一个项目,我必须用双变量进行一些数学计算。 问题是我在SUN Solaris 9和Linux上得到的结果不同。 有很多方法(在这里和其他论坛中解释)可以让Linux像Sun一样工作,但不是相反。 我不能触摸Linux代码,所以只有SUN可以更改。 有没有办法让SUN像Linux一样运行 我运行的代码(在两个系统上使用gcc编译): 如果输入为339886769243483 Linux中的输出:如何使SUN上的gcc以与Linux中相同的方式计算浮点,linux,floating-point,solaris,Linux,Floating Point,Solaris,我有一个项目,我必须用双变量进行一些数学计算。 问题是我在SUN Solaris 9和Linux上得到的结果不同。 有很多方法(在这里和其他论坛中解释)可以让Linux像Sun一样工作,但不是相反。 我不能触摸Linux代码,所以只有SUN可以更改。 有没有办法让SUN像Linux一样运行 我运行的代码(在两个系统上使用gcc编译): 如果输入为339886769243483 Linux中的输出: lnum => 339886769243**483**.00000000000000000
lnum => 339886769243**483**.00000000000000000000
lnum => 33988676.9243**4829473495483398**
product => 20819503.600158**59827399253845**
在阳光下:
lnum => 339886769243483.00000000000000000000
lnum => 33988676.92434830218553543091
product = 20819503.600158**60199928283691**
注意:结果并不总是不同的,而且大多数时候是相同的。60000个数字中只有10个15位数有这个问题
请帮忙 有两件事:
- 您需要阅读以下内容:
- 您需要确定应用程序中对数值精度的要求
-fexcess precision=standard
是否确实消除了x87系统上的双舍入;我认为答案取决于FLT_EVAL_方法的值。我没有32位Linux/x86机器便于测试。]
但我不知道如何修复Solaris结果以与Linux结果匹配,我也不确定您为什么要这样做:您将使Solaris结果更不准确,而不是使Linux结果更准确
[编辑:caf在这里有一个很好的建议。在Solaris上,尝试故意使用long double作为中间结果,然后强制返回到double。如果操作正确,这将重现您在Linux中看到的双舍入效果。]
请参阅David Monniaux的优秀论文,了解双舍入的良好解释。这是在前面的回答中提到的Goldberg文章之后的重要阅读。您应该将
lnum
初始化为0-因为您很幸运,结果不完全是垃圾。我大胆猜测,您在32位Lin上也会得到不同的结果ux和64位Linux。这是真的吗?如果是的话,这对你有关系吗?OP可以尝试在SPARC上用长双精度
进行计算,然后将结果四舍五入为双精度
——模拟扩展精度x87计算的效果。但这不能保证有效。@caf:好的一点——绝对值得一试但是,在其他一些平台上,它会再次给出不同的结果——例如,OS X/PPC,其中“long double”是一种特殊的“double double”格式,或者Windows,其中“long double”似乎与“double”相同。也许这与OP的需要无关。我想这里的真正答案是另一个问题:“你为什么需要这个?”@Mark Dickinson:谢谢你的详细解释。我明白我想让SUN“错误地”工作。关于原因:我有一个系统使用上述代码(在Linux上)多年来。现在我在SUN上编写了另一个应用程序,它将使用相同的代码并提供相同的输入以产生相同的结果。只要我在SUN和Linux上有相同的值,计算的实际“正确性”就不重要了。@caf:谢谢,我试过了,它在部分情况下有所帮助,但不是所有情况下都有帮助。在第一个例子中不过,计算方面,lnum=lnum*10.0E-8
帮助更大。我稍后会尝试更多的组合。也许有一些编译器标志可以帮助您?@Marina:很可能x87版本没有将中间结果四舍五入到双精度
(您必须检查程序集才能确定),因此,请尝试在长双精度
中进行所有计算,直到最后一步才进行取整。不过,为了获得完美的复制,您可能必须以某种方式将中间结果取整为80位尾数(SPARC的长双精度
有112位尾数)。
lnum => 339886769243483.00000000000000000000
lnum => 33988676.92434830218553543091
product = 20819503.600158**60199928283691**