浮点导致计算不准确

Floating point that make the calculation inaccurate

提问人:Vito 提问时间:1/24/2017 最后编辑:Andrey DeinekoVito 更新时间:1/24/2017 访问量:573

问:

我没有在 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 

由于最终答案经过了许多步骤的计算,因此变得不准确。

Ruby-on-Rails Ruby 点浮 精度

评论

0赞 Stefan 1/24/2017
“我没有设置数据类型”——你可能没有意识到,但你意识到了:显式转换为浮点数。n.to_fn
0赞 Vito 1/24/2017
@Stefan浮点是指无限的小数点?-->计算不准确 -->避免在计算中使用?
0赞 Stefan 1/24/2017
浮点数是近似值,请参阅下面的答案。
0赞 Simon Byrne 1/24/2017
我认为你的代码可能是错误的:你不应该需要平方,而且不清楚从哪里来。除了少数边缘情况(例如,当所有值都相同或具有非常大的值时),浮点误差通常应该相当小。sd_sumaverage
0赞 Vito 1/24/2017
@Simon Byrne,我简化了代码。不用担心

答:

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浮点数是近似值,因为它们必须存储的位数有限。