ruby 中的算术

发布于 2024-08-05 10:23:35 字数 200 浏览 3 评论 0原文

为什么 ruby​​ 中的代码 7.30 - 7.20 返回 0.0999999999999996,而不是 0.10

但如果我写 7.30 - 7.16,例如,一切都会好的,我会得到 0.14

有什么问题,我该如何解决?

Why this code 7.30 - 7.20 in ruby returns 0.0999999999999996, not 0.10?

But if i'll write 7.30 - 7.16, for example, everything will be ok, i'll get 0.14.

What the problem, and how can i solve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

落在眉间の轻吻 2024-08-12 10:23:36

这是浮点数在内存中表示方式的常见错误。

如果需要精确结果,请使用 BigDecimal。

result=BigDecimal.new("7.3")-BigDecimal("7.2")
puts "%2.2f" % result

That is a common error from how float point numbers are represented in memory.

Use BigDecimal if you need exact results.

result=BigDecimal.new("7.3")-BigDecimal("7.2")
puts "%2.2f" % result
み格子的夏天 2024-08-12 10:23:36

有趣的是,在一种基数中具有很少小数位的数字通常在另一种基数中具有大量小数。例如,以 10 为基数表示 1/3 (=0.3333...) 需要无数位小数,但以 3 为基数表示只需要一位小数。同样,要表示数字 1/10 ( =0.1) 在基数 2 中。

It is interesting to note that a number that has few decimals in one base may typically have a very large number of decimals in another. For instance, it takes an infinite number of decimals to express 1/3 (=0.3333...) in the base 10, but only one decimal in the base 3. Similarly, it takes many decimals to express the number 1/10 (=0.1) in the base 2.

遗心遗梦遗幸福 2024-08-12 10:23:36

由于您正在进行浮点数学计算,因此返回的数字就是您的计算机用于精度的数字。

如果您想要更接近的答案,达到设定的精度,只需将浮点数乘以该精度(例如乘以 100),将其转换为 int,进行数学计算,然后除以。

还有其他解决方案,但我发现这是最简单的,因为四舍五入对我来说总是有点不确定。

之前已经有人问过这个问题,您可能想查找之前给出的一些答案,例如:
处理浮点数的精度问题

Since you are doing floating point math then the number returned is what your computer uses for precision.

If you want a closer answer, to a set precision, just multiple the float by that (such as by 100), convert it to an int, do the math, then divide.

There are other solutions, but I find this to be the simplest since rounding always seems a bit iffy to me.

This has been asked before here, you may want to look for some of the answers given before, such as this one:
Dealing with accuracy problems in floating-point numbers

︶葆Ⅱㄣ 2024-08-12 10:23:35

问题是,我们可以轻松地以十进制书写的一些数字在当前硬件实现的特定浮点格式中没有精确的表示。一种简单的表述方式是所有整数都如此,但不是所有分数,因为我们通常用 2**e 指数存储分数。因此,您有 3 个选择:

  1. 适当舍入。未四舍五入的结果总是非常非常接近,因此四舍五入的结果总是“完美”。这就是 Javascript 所做的事情,很多人甚至没有意识到 JS 所做的一切都是浮点数。

  2. 使用定点运算。 Ruby 实际上使这变得非常简单;它是唯一一种随着数字变大而从 Fixnum 无缝转换到 Bignum 类的语言。

  3. 使用旨在解决此问题的类,例如 BigDecimal

查看问题更详细,我们可以尝试用二进制表示你的“7.3”。 7部分很简单,111,但是我们怎么做0.3呢? 111.1 是 7.5,太大了,111.01 是 7.25,越来越接近。事实证明,111.010011 是“下一个最接近的较小数字”,7.296875,当我们尝试填写缺失的 .003125 时,最终我们发现它只是 111.010011001100110011...永远无法用我们选择的有限位字符串编码来表示。

The problem is that some numbers we can easily write in decimal don't have an exact representation in the particular floating point format implemented by current hardware. A casual way of stating this is that all the integers do, but not all of the fractions, because we normally store the fraction with a 2**e exponent. So, you have 3 choices:

  1. Round off appropriately. The unrounded result is always really really close, so a rounded result is invariably "perfect". This is what Javascript does and lots of people don't even realize that JS does everything in floating point.

  2. Use fixed point arithmetic. Ruby actually makes this really easy; it's one of the only languages that seamlessly shifts to Class Bignum from Fixnum as numbers get bigger.

  3. Use a class that is designed to solve this problem, like BigDecimal

To look at the problem in more detail, we can try to represent your "7.3" in binary. The 7 part is easy, 111, but how do we do .3? 111.1 is 7.5, too big, 111.01 is 7.25, getting closer. Turns out, 111.010011 is the "next closest smaller number", 7.296875, and when we try to fill in the missing .003125 eventually we find out that it's just 111.010011001100110011... forever, not representable in our chosen encoding in a finite bit string.

怀中猫帐中妖 2024-08-12 10:23:35

问题是浮点不准确。您可以使用 Rational、BigDecimal 或普通整数来解决这个问题(例如,如果您想存储金钱,您可以将美分数量存储为 int,而不是将美元数量存储为浮点数)。

BigDecimal 可以准确地存储以 10 为基数的有限位数的任何数字,并对没有有限位数的数字进行四舍五入(因此三分之三不是整数)。

有理数可以准确地存储任何有理数,而根本不能存储无理数。

The problem is that floating point is inaccurate. You can solve it by using Rational, BigDecimal or just plain integers (for example if you want to store money you can store the number of cents as an int instead of the number of dollars as a float).

BigDecimal can accurately store any number that has a finite number of digits in base 10 and rounds numbers that don't (so three thirds aren't one whole).

Rational can accurately store any rational number and can't store irrational numbers at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文