Floating point 朱莉娅:如何处理浮点的精确性
我遇到过浮点数精度不精确的情况。正如我在下面的代码的简化版本中所展示的,我在相同的场景中计算一个和,在最后的小数中我得到不同的值。这是有关的 我想知道是否有任何方法可以解决这个问题,例如某种截断Floating point 朱莉娅:如何处理浮点的精确性,floating-point,julia,precision,Floating Point,Julia,Precision,我遇到过浮点数精度不精确的情况。正如我在下面的代码的简化版本中所展示的,我在相同的场景中计算一个和,在最后的小数中我得到不同的值。这是有关的 我想知道是否有任何方法可以解决这个问题,例如某种截断 s1 = zero(Float64) s = zero(Float64) for a in 1:10000 for k in 1:4 temp=log(1e-5) s1+=temp s +=temp end end s2 = zero(Fl
s1 = zero(Float64)
s = zero(Float64)
for a in 1:10000
for k in 1:4
temp=log(1e-5)
s1+=temp
s +=temp
end
end
s2 = zero(Float64)
for a in 1:10000
for k in 1:4
temp = log(1e-5)
s2+=temp
s+=temp
end
end
s1+s2 == s ###FALSE
s < s1+s2 ###TRUE
s1=0(浮点64)
s=零(浮点数64)
以1:10000的比例计算
1:4中的k
温度=对数(1e-5)
s1+=温度
s+=温度
结束
结束
s2=零(浮点数64)
以1:10000的比例计算
1:4中的k
温度=对数(1e-5)
s2+=温度
s+=温度
结束
结束
s1+s2==s####假
s
浮点加法不是:由于中间舍入,更改加法顺序可能会产生细微不同的结果
您可以做以下几件事:
sum\u kbn
:julia>sum_kbn(a=1:10000,k=1:4的对数(1e-5))
-460517.01859880914
isapprox
(也可通过中缀≈代码>)。这接受分别用于指定绝对和相对公差的atol
和rtol
可选参数
s1+s2≈ s
浮点加法不是:由于中间舍入,更改加法顺序可能会产生细微不同的结果
您可以做以下几件事:
sum\u kbn
:julia>sum_kbn(a=1:10000,k=1:4的对数(1e-5))
-460517.01859880914
isapprox
(也可通过中缀≈代码>)。这接受分别用于指定绝对和相对公差的atol
和rtol
可选参数
s1+s2≈ s
浮点64表示IEEE 754格式的数字。在64位中,尾数占52位。这意味着精度约为15位小数
在第一次循环之后,s1
和s
应该是相同的
差异发生在第二个循环体中。temp
中的数字始终相同<当第一次进入第二个循环的循环体时,code>s几乎是temp*40000.0
。将temp
添加到s
时,会导致temp
的最后4.5位数字丢失。这就是差异的原因,因为s2
将为零,添加temp
将使用temp
的所有数字
顺便说一下,s、s1+s2
中没有一个(以编程方式)与temp*80000.0
相同(从数学上讲,所有3个数字都应该相同)
因此,为了减少数字错误,请遵守规则
- 更喜欢乘法,它们保持精度
- 数字越相等,相加就越精确。您按照
的顺序丢失了精度(而a/b
)a=abs(a),b=abs(b),a>b,b!=0
- 相减的数字越相等,精度就越低。按照前导公共数字或更确切地说是位的顺序降低精度
浮点64表示IEEE 754格式的数字。在64位中,尾数占52位。这意味着精度约为15位小数 在第一次循环之后,
s1
和s
应该是相同的
差异发生在第二个循环体中。temp
中的数字始终相同<当第一次进入第二个循环的循环体时,code>s几乎是temp*40000.0
。将temp
添加到s
时,会导致temp
的最后4.5位数字丢失。这就是差异的原因,因为s2
将为零,添加temp
将使用temp
的所有数字
顺便说一下,s、s1+s2
中没有一个(以编程方式)与temp*80000.0
相同(从数学上讲,所有3个数字都应该相同)
因此,为了减少数字错误,请遵守规则
- 更喜欢乘法,它们保持精度
- 数字越相等,相加就越精确。您按照
的顺序丢失了精度(而a/b
)a=abs(a),b=abs(b),a>b,b!=0
- 相减的数字越相等,精度就越低。按照前导公共数字或更确切地说是位的顺序降低精度
可能重复使用<代码>≈代码>(\approx)而不是
=
<代码>s1+s2≈ s#=>true非重复:这是关于解决特定语言中浮点问题的策略,而不是它发生的原因。可能重复使用≈代码>(\approx)而不是=
<代码>s1+s2≈ s#=>true
不是重复:这是关于解决特定语言中浮点问题的策略,而不是它发生的原因。
s1 = zero(Float64)
s = zero(Float64)
for a in 1:40000
temp=log(1e-5)
s1+=temp
s +=temp
end
s2 = zero(Float64)
for a in 1:40000
temp = log(1e-5)
s2+=temp
s+=temp
end
sm = 80000.0 * log(1e-5);
println(s1+s2 == s)
println(s < s1+s2)
println(s == sm)
println(s1+s2 == sm)
println(s1+s2)
println(sm)
println(s)
false
true
false
false
-921034.0371971375
-921034.0371976183
-921034.0371986133