Erlang docs说:
将整数与浮点型进行比较时,除非运算符是=:=或=/=之一,否则精度较低得项将转换为另一项得类型.除非浮点型得所有有效数字都位于小数点得左侧,否则浮点型比整数更精确.当浮点型大于/未来+/-9007199254740992.0时,会发生这种情况.转换策略将根据浮点型得大小而改变,因为否则比较大浮点型与整数将失去传递性.
如何观察到大浮点数转换策略的变化?
我读到的文档中说,对于(...digits)
的小序列,(...digits).0 == (...digits)
为假,但对于更大的序列(...位数),(...digits).0 == (...digits)
为真,但对于他们给出的值,情况似乎并非如此:
> 9007199254740992.0 == 9007199254740992
true
> 9.0 == 9.
true
然而,对于较大的数字来说,情况似乎确实如此。关于转换策略变化的具体边界,文档是否过时了?
> 999999999999999999999.0 == 999999999999999999999.
false
> 9.0 == 9.
真的
为什么?
对较大数字的浮点整数比较策略进行更改的原因<->是“否则大浮点数和整数的比较将失去传递性”。我不明白-是否有此算法如何避免传递性失败的示例?
2条答案
按热度按时间bsxbgnwa1#
让我们考虑这三个数字:
在实际规则下,
A
和C
彼此相等,但不同于B
:如果是相反的方式,在与浮点数比较之前,将大于阈值的整数转换为浮点数,会怎么样?
所以现在看起来
A
和B
都等于C
,但彼此不相等,相等比较失去了传递性。9007199254740992等于253,而53也是64位IEEE 754浮点数 * 中的有效位数,因此对于大于此值的数字,浮点类型不能表示所有整数。例如,
9007199254740992.0 + 1 == 9007199254740992.0
返回true
。这就是Erlang整数类型(它是一个bignum,因此可以表示任意大的整数)被认为在此阈值之上更精确。pokxtpni2#
Given that floats and integers have different precissions (floats have higher resolution with values closer to 0 and lower resolution with values further away from 0), if you want to compare them you need to transform one of them to the other.
If this transformation is from the one with higher precission to the one of lower precission, this would be possible:
For this reason (transitivity), the transformation is performed the other way around, from lower precssion to higher precission.