使计算不准确的浮点数

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 

最终答案经过多步计算,不准确

为了保持计算的准确性,请使用 BigDecimal instead of Float:

 scores = params[:scores].split("\r\n").map { |n| BigDecimal(n) }

BigDecimal provides support for very large or very accurate floating point numbers.

Decimal arithmetic is also useful for general calculation, because it provides the correct answers people expect–whereas normal binary floating point arithmetic often introduces subtle errors because of the conversion between base 10 and base 2.

Ruby(或 IEEE)的浮点数是实数的近似值。 in-depth 解释可以在这里找到:What Every Computer Scientist Should Know About Floating-Point Arithmetic.

不幸的是,浮点数显示时好像它们是准确的,这会导致很多混淆。如果显示 exact 值会更清楚,它们是:

2.32  #=> 2.319999999999999840127884453977458178997039794921875
23.0  #=> 23.0
65.76 #=> 65.7600000000000051159076974727213382720947265625

以上三个数字,只有23.0可以准确表示,另外两个是实际数字的近似值(一个略低于,一个略高于)。我认为很明显,您不能期望从这些结果中获得准确的结果。