如何解决为什么在Erlang中会根据浮点数的大小更改[integer <-> float]转换策略,我该如何观察呢?
“将整数与浮点数进行比较时,精度较低的项将转换为另一项的类型,除非运算符为=:=或= / =之一。浮点数比整数更精确直到浮点数的所有有效数字都位于小数点的左侧,这会在浮点数大于/小于+/- 9007199254740992.0时发生。转换策略会根据浮点数的大小而变化,因为否则会比较大浮点数和整数将失去其传递性。“
如何观察到大流通量转换策略的这种变化?
我在阅读文档时说,(...digits).0 == (...digits)
对于(...digits)
的一小序列将为false,但对于较大的序列(...数字)将为true,但事实并非如此他们给的价值:
> 9007199254740992.0 == 9007199254740992
true
> 9.0 == 9.
true
但是,似乎更大的数字确实如此。有关转换策略更改的特定范围,文档是否过时?
> 999999999999999999999.0 == 999999999999999999999.
false
> 9.0 == 9.
true
为什么?
为大数更改浮点数整数比较策略的原因是“否则,比较大的浮点数和整数将失去其可传递性”。我不了解-是否有示例说明该算法如何避免传递失败?
解决方法
让我们考虑以下三个数字:
A = 9007199254740992.
B = 9007199254740993.
C = 9007199254740992.0.
在实际规则下,A
和C
彼此相等,并且不同于B
:
> A == B. %% A and B are both integers,compared as integers
false
> A == C. %% C gets converted to an integer before comparison
true
> B == C. %% C gets converted to an integer before comparison
false
如果反过来,将阈值以上的整数在与浮点数比较之前转换为浮点数怎么办?
> A == B. %% no change,because they are both integers
false
> float(A) == C. %% no surprise here
true
> float(B) == C. %% B cannot be accurately represented as a floating point value!
true
所以现在看起来A
和B
都等于C
,但彼此不相等,并且相等比较失去了可传递性。
9007199254740992等于2 53 ,并且53也是64位IEEE 754浮点数 * 中的有效位数,因此对于大于这个浮点类型不能代表每个整数。例如,9007199254740992.0 + 1 == 9007199254740992.0
返回true
。因此,在此阈值以上,认为Erlang整数类型(是一个大数字,因此可以表示任意大的整数)更为精确。
*二进制表示形式仅使用52位作为有效位,并且由于第一位几乎始终为1而忽略了这一点。搜索“次正规数”以了解更多信息。
,鉴于浮点数和整数具有不同的精度(浮点数具有较高的分辨率,其值接近0,较低的分辨率,其值与0距离更远),如果要比较它们,则需要将它们之一转换为另一个。 / p>
如果此转换是从较高精度的转换到较低精度的转换,则有可能:
H2 = H1 + Delta,true = L == H1,true = L == H2,true = H1 /= H2. %% In this case,both H1 and H2 are equal to L but different between themselves
由于这个原因(传递性),变换是从较低的精度向较高的精度进行的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。