【问题标题】:Floating point that make the calculation inaccurate使计算不准确的浮点数
【发布时间】:2017-06-08 21:15:57
【问题描述】:

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

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

【问题讨论】:

  • “我没有设置数据类型” – 你可能不知道,但你做到了:n.to_f 明确地将n 转换为浮点数。
  • @Stefan 浮点数指无限小数点? -->不准确的计算-->避免在计算中使用?
  • 浮点数是近似值,请参阅下面的答案。
  • 我认为您的代码可能是错误的:您不需要平方 sd_sum,而且尚不清楚 average 的来源。除了少数极端情况(例如所有值都相同,或者您的值非常大)之外,浮点错误通常应该是相当小的。
  • @Simon Byrne 我简化了代码。不用担心

标签: ruby-on-rails ruby floating-point floating-accuracy


【解决方案1】:

为了保持计算的准确性,请使用BigDecimal 而不是Float

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

BigDecimal 提供对非常大或非常精确的支持 浮点数。

十进制算术对于一般计算也很有用,因为它 提供人们期望的正确答案——而普通的二进制 浮点运算通常会引入细微的错误,因为 基数 10 和基数 2 之间的转换。

【讨论】:

  • 你能解释一下 bigdecimal 的用法吗?
  • @Vito:见here
  • @Andrey Deineko 浮点数指无限小数点? -->不准确的计算-->避免在计算中使用?
  • @Vito 正确,始终使用小数进行准确计算。
  • bigdecimal=十进制?
【解决方案2】:

Ruby(或 IEEE)的浮点数是实数的近似值。深入的解释可以在这里找到: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可以准确表示,另外两个是实际数字的近似值(一个略低于,另一个略高于)。我认为很明显,您不能期望从这些中得到准确的结果。

【讨论】:

  • 那篇文章的重点是浮点数实数(嗯,除了 Inf 和 NaN):这是对它们的操作(算术,转换为/从小数)是近似值。
  • @SimonByrne 我应该更精确一点,IEEE 浮点数是近似值,因为它们必须存储的位数有限。
猜你喜欢
  • 1970-01-01
  • 2022-06-10
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-30
相关资源
最近更新 更多