提问人:Vito 提问时间:1/24/2017 最后编辑:Andrey DeinekoVito 更新时间:1/24/2017 访问量:573
浮点导致计算不准确
Floating point that make the calculation inaccurate
问:
我没有在 ruby 中设置变量的日期类型。我使用默认数据类型,以便使最终计算不准确。如何解决?
scores = params[:scores].split("\r\n").map { |n| n.to_f } # array of scores (at most 2 decimal points,e.g 2.32 ,23,65.76.....)
#new array
sd=Array.new(scores.length,0)
sd[0]= (scores[0]-average)**2 # calculation <<== sd[i] become 234.08999999999992
470.8900000000001
13.69000000000002
0.6399999999999955
86.48999999999995
sd[1]= (scores[1]-average)**2
sd[2]= (scores[2]-average)**2
sd[3]= (scores[3]-average)**2
sd[4]= (scores[4]-average)**2
sd_sum=sd[0]+sd[1]+sd[2]+sd[3]+sd[4]
sd_sum=sd_sum**2 ...
gg=sd_sum/5 # further calculation
ans=Math.sqrt(gg) # final answer for standard deviation
由于最终答案经过了许多步骤的计算,因此变得不准确。
答:
2赞
Andrey Deineko
1/24/2017
#1
为了保持计算的准确性,请使用 BigDecimal 而不是 Float:
scores = params[:scores].split("\r\n").map { |n| BigDecimal(n) }
BigDecimal
为非常大或非常准确的提供支持 浮点数。十进制算术对于一般计算也很有用,因为它 提供人们期望的正确答案——而普通二进制 浮点运算经常会引入细微的误差,因为 以 10 为基数和以 2 为基数之间的转换。
评论
0赞
Vito
1/24/2017
你能解释一下Bigdecimal的用法吗?
0赞
user1934428
1/24/2017
@Vito:看这里
0赞
Vito
1/24/2017
@Andrey Deineko 浮点是指无限小数点?-->计算不准确 -->避免在计算中使用?
0赞
Andrey Deineko
1/24/2017
@Vito正确,请始终使用小数进行准确计算。
0赞
Vito
1/24/2017
bigdecimal= 十进制 ?
2赞
Stefan
1/24/2017
#2
Ruby(或IEEE)浮点数是实数的近似值。可以在此处找到深入的解释:每个计算机科学家都应该了解的浮点运算。
不幸的是,浮点数显示得好像它们是准确的,这导致了很多混淆。如果显示确切的值,则会更清楚,它们是:
2.32 #=> 2.319999999999999840127884453977458178997039794921875
23.0 #=> 23.0
65.76 #=> 65.7600000000000051159076974727213382720947265625
从上面的三个数字中,只能精确表示,另外两个是实际数字的近似值(一个略低于,另一个略高于)。我认为很明显,你不能指望从中得到准确的结果。23.0
评论
0赞
Simon Byrne
1/24/2017
那篇文章的要点是浮点数是实数(好吧,除了 Inf 和 NaN):它们的运算(算术、与十进制的转换)是近似的。
0赞
Stefan
1/24/2017
@SimonByrne我应该更准确地说,IEEE浮点数是近似值,因为它们必须存储的位数有限。
评论
n.to_f
n
sd_sum
average