这是1990年的事情
这将可能是一个被忽略的或有争议的答案,但我觉得它需要说。
其他人已将注意力集中在“浮点”计算(例如涉及一个或多个“双打”数字的计算)上的消息近似为数学。
我对这个答案的关注点在于,即使在普通Java代码中使用这种方式,并且在大多数编程语言中的普通代码中,数字如0.1
的计算不必是近似值。
几种语言治疗号码,如0.1
为有理数,两个整数之间的比率(分子分母上,在这种情况下1
超过10
或十分之一),就像他们在学校的数学。只包含整数和有理数的计算是100%准确的(忽略整数溢出和/或OOM)。
不幸的是,如果分母变得太大,理性计算会变得很慢。
有些语言采取妥协的立场。他们把一些理性看作是理性的(所以100%的准确性),只有100%的准确性才会放弃,当理性的计算在病态上是缓慢的时候,转换为漂浮。
例如,这里是一个相对较新的和前瞻性的编程语言的一些代码:
sub Power(\base, \exp) {
given exp {
when 0 { 1.0 }
when * >= 1 { base * Power(base, exp - 1) }
default { 1.0/base * Power(base, exp + 1) }
}
}
这在重复这个其他语言代码。
现在使用这个函数来获得结果的指数的列表:
for 1000,20,2,1,0,-1,-2,-20,-1000 -> \exp { say Power 5, exp }
Running this code in glot.io显示:
9332636185032188789900895447238171696170914463717080246217143397959
6691097577563445444032709788110235959498993032424262421548752135403
2394841520817203930756234410666138325150273995075985901831511100490
7962651131182405125147959337908051782711254151038106983788544264811
1946981422866095922201766291044279845616944888714746652800632836845
2647429261829862165202793195289493607117850663668741065439805530718
1363205998448260419541012132296298695021945146099042146086683612447
9295203482686461765792691604742006593638904173789582211836507804555
6628444273925387517127854796781556346403714877681766899855392069265
4394240087119736747017498626266907472967625358039293762338339810469
27874558605253696441650390625
95367431640625
25
5
1
0.2
0.04
0.000000000000010
0
上述结果是100%准确 - 直到最后的指数,-1000
。我们可以看到在语言上的准确率100%放弃,如果我们检查结果的类型(使用WHAT
):
for 1000,20,2,1,0,-1,-2,-20,-1000 -> \exp { say WHAT Power 5, exp }
显示:
(Rat)
(Rat)
(Rat)
(Rat)
(Rat)
(Rat)
(Rat)
(Rat)
(Num)
转换Rat
秒(默认理性型)成FatRat
S(任意精度理性型)避免不准确甚至经病理大分母:
sub Power(\base, \exp) {
given exp {
when 0 { 1.0.FatRat }
when * >= 1 { base * Power(base, exp - 1) }
default { 1.0.FatRat/base * Power(base, exp + 1) }
}
}
这产生同样显示为我们的原代码,除了它出来作为最后的计算:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
我不知道这是正确的,但是,AIUI,它应该是。
汤姆斯科特做了一个伟大的视频解释这个https://www.youtube.com/watch?v=PZRI1IfStY0 – SpiderPig
http://stackoverflow.com/questions/8511312/java-double-variables-have-strange-values –
重新开放以指出减少此特定程序的舍入误差的策略。 –