java比较浮点数及其副本
我知道比较两个doubles
是有问题的,如果它们是从不同的计算中获得的。但当其中一个是另一个的副本(价值)时,这是否也成立。下面几行解释了这个场景。如果我有这样的问题
double a,b;
a=randdouble();/*some double value*/
b=a;
然后
Q1)对于C编译器,比较a==b
是否总是保证返回true
(我有gcc 6.1.1
)
问题2)如果我使用malloc
在堆内存中分配变量a
和b
,上面的答案会保持不变吗
问题3)如果我用JAVA编译器(我正在使用Open JDK 1.7.0
)替换C编译器,当然要进行必要的语法更改,上述答案是否会保持不变
编辑1:数字a
和b
是!= NaN
# 1 楼答案
问题1:由于
NaN
比较本身不相等,因此不能保证比较结果为真。可能还有其他情况,但NaN
是一个明显的反例问题2:变量在内存中的位置没有区别
问题3:我希望Java也有类似的表现
撇开这一特殊情况不谈,我相信标准并没有给出这样的保证:
想象一个ABI,其中
double
表达式被计算,值以80位精度返回(英特尔80x87堆栈),但存储为64位IEEE-754双精度。即使randdouble()
被定义为返回一个double
,与long double
相反,它的返回值可能比存储在a
或b
中的值更精确。取决于编译器如何优化randdouble()
函数调用和比较a == b
之间的各种表达式,它可能最终会将80位的精确返回值与其通过转换为64位并返回80位获得的近亲进行比较。如果转换过程中精度降低,则比较将失败。我将尝试从标准中找到一个适当的引用来支持这一点,但这似乎是合理的,尽管a
或b
是局部变量还是存储在堆上可能会对执行的转换顺序产生影响,但对其中一种或另一种情况假设任何保证都是不明智的