double乘以整数精度

时间:2011-05-18 07:30:30

标签: c++

我有3.4的双倍。但是,当我将它乘以100时,它会得到339而不是340.这似乎是由double的精度引起的。我怎么能绕过这个?

由于

5 个答案:

答案 0 :(得分:3)

首先发生了什么:

  1. 3.4不能完全表示为二进制分数。因此,实现选择可表示的最接近的二进制分数。我不确定它是否总是向零舍入,但在你的情况下,代表的数字确实更小。
  2. 转换为整数 truncates ,即使用绝对值较小的最接近的整数
  3. 由于两次转换都偏向同一方向,因此您始终可以获得舍入错误。
  4. 现在你需要知道你想要什么,但是你可能想要使用对称舍入,即找到最接近的整数,无论​​它是更小还是更大。这可以实现为

    #include <cmath>
    int round(double x) { std::floor(x + 0.5); } // floor is provided, round not
    

    int round(double x) { return x < 0 ? x - 0.5 : x + 0.5; }
    

    我不完全确定它确实向零舍入,所以如果您使用它,请验证后者。

答案 1 :(得分:2)

如果您需要完全精确,可能需要使用类似Boost.Rational的内容。

答案 2 :(得分:1)

您可以使用两个整数,并将小数部分乘以乘数/ 10.

E.g

int d[2] = {3,4};
int n = (d[0] * 100) + (d[1] * 10);

如果你真的想要小数点两边的所有精度。真的取决于应用程序。

答案 3 :(得分:1)

浮点值很少是准确的。不幸的是,当将浮点值转换为C中的整数时,该值将向下舍入为零。这意味着如果你有339.999999,那么演员的结果将是339。

要解决此问题,您可以从值中添加(或减去)“0.5”。在这种情况下,339.99999 + 0.5 =&gt; 340.499999 =&gt; 340(转换为int时)。

或者,您可以使用标准库提供的众多转换函数之一。

答案 4 :(得分:0)

您没有值为3.4的double,因为3.4不是 可表示为双(至少在普通机器上,和 大多数外来物种也是如此)。你拥有的是非常有价值的东西 接近3.4。乘法后,你有一些非常值 接近340.但肯定不是399。

你在哪里看到399?我猜你很简单 使用int转换为static_cast,因为此操作 截断为零。其他操作可能会做什么 你想要的:输出固定格式,后面有0个位置 十进制,例如,rounds(在实现中定义 方式,但我所知道的所有实现都使用了 默认情况下);函数round向最近的舍入舍入 在中途情况下远离零(但你的结果不会 在中途附近的任何地方)。这是用于的舍入 商业应用。

真正的问题是你在做什么需要精确的 积分值。根据应用程序的不同,可能会更多 适合使用intlong,将实际值缩放为 必要的(即存储100倍的实际值,或 无论如何),或某种十进制算术包,而不是 而不是使用double