gpt4 book ai didi

ruby-on-rails - Ruby float 学 - Sum Calc 中的精度问题

转载 作者:数据小太阳 更新时间:2023-10-29 07:03:58 29 4
gpt4 key购买 nike

大家早上好

我在 float 学方面遇到了一些问题,完全迷失在“.to_f”、“*100”和“.0”中!

我希望有人能帮助我解决我的具体问题,并准确解释他们的解决方案为何有效,以便我下次理解这一点。

我的程序需要做两件事:

  1. 对一组小数求和,确定它们的和是否正好为 1.0
  2. 确定 1.0 与数字总和之间的差值 - 将变量的值设置为使总和等于 1.0 的精确差值。

例如:

  1. [0.28, 0.55, 0.17] -> 总和应为 1.0,但我一直得到 1.xxxxxx。我正在以下列方式实现总和:

    sum = array.inject(0.0){|sum,x| sum+ (x*100)} / 100
  2. 我需要此功能的原因是我正在读取一组来自 excel 的小数。它们并非 100% 精确(缺少一些小数点),因此总和通常为 0.999999xxxxx 或 1.000xxxxx。例如,我将获得如下值:

    0.568887955,0.070564759,0.360547286

为了解决这个问题,我可以先取前 n-1 个数字的总和,然后稍微改变最后的数字,使所有数字的总和为 1.0(必须使用上面的等式或其他任何我满足的验证以结束)。我目前正在按如下方式实现:

          sum = 0.0
array.each do |item|
sum += item * 100.0
end
array[i] = (100 - sum.round)/100.0

我知道我可以用 inject 做到这一点,但我试着用它看看有什么用。我认为这通常是有效的(通过检查输出),但它并不总是满足上面的验证总和。所以如果需要的话我也可以调整这个。请注意,我只需要这些数字中的两位小数精度 - 即 0.56 而不是 0.5623225。我可以在演示时或在计算期间将它们四舍五入...这对我来说无关紧要。

非常感谢您的帮助!

最佳答案

如果准确性对您很重要,则不应使用浮点值,根据定义,浮点值是不准确的。 Ruby 有一些精确的数据类型,用于在准确性很重要的情况下进行算术运算。他们是,离开我的头顶,BigDecimal , RationalComplex ,具体取决于您实际需要计算的内容。

在你的情况下,你正在寻找的似乎是BigDecimal,它基本上是一个具有固定位数的数字,其中小数点后有固定位数(与 float 相比点,小数点后有任意位数)。

当您从 Excel 读取并故意将“0.9987”等字符串转换为 float 时,您会立即丢失字符串中包含的准确值。

require "bigdecimal"
BigDecimal("0.9987")

这个值是精确的。它是 0.9987。不是 0.998732109 或任何接近它的值,而是 0.9987。您可以对它使用所有常用的算术运算。如果您不将 float 混合到算术运算中,返回值将保持精确。

如果您的数组包含您从 Excel 获得的原始字符串(即您没有#to_f'd 它们),那么这将为您提供一个 BigDecimal,它是它们之和的差值和 1.

1 - array.map{|v| BigDecimal(v)}.reduce(:+)

关于ruby-on-rails - Ruby float 学 - Sum Calc 中的精度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10785487/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com