【问题标题】:C++ Store double in int variable errorC ++在int变量中存储双精度错误
【发布时间】:2014-09-09 12:56:24
【问题描述】:

这是一个小程序,用于计算“从”“到”两个数字之间的“间隔”大小的差距。然后我计算“大小”(间隙数)并将其存储在一个 int 变量中,有时给我一个较小的值。

代码如下:

double from=0, to=1, interval=0.1;

cout << "WORKING WITH VARIABLES: " << endl;
double operation = (to-from)/interval +1;
cout << "Size: " << operation << endl;

int size = operation;

cout << "Size after storing: " << size << endl << endl;

cout << "WORKING WITHOUT VARIABLES: " << endl;
cout << "Size: " << (to-from)/interval +1 << endl;

size = (to-from)/interval +1;

cout << "Size after storing: " << size << endl << endl;

问题似乎在于它的存储间隔。如果 interval=1 一切都很好,但如果是 0.1,如在示例中它给我 10 而不是 11 在第二种情况的“存储后的大小”。

我发现它适用于区间=0.25 (2^-2)。

编辑:我没有发现它在第一种情况下会失败,在第二种情况下总是会失败。

【问题讨论】:

  • 我认为这只是由于 double 对象的表示。例如,从0.999999 转换为int 将是0.0,但从1.000000001 转换为int 将是1.0
  • 你用的是什么编译器?我用 xcode (clang) 和 g++ 得到了正确的结果
  • 您是否尝试调试并查看数字在哪个位置出错?检查 (to-from)/interval 操作返回什么。
  • @IAmJohn 我正在使用 MinGW32 g++
  • @PiotrChojnacki 操作返回正确的值,在第一种情况下检查。

标签: c++ floating-point integer


【解决方案1】:

浮点数以有限精度和二进制形式存储。 0.25 很容易。那只是 1/4,所以 0.01 二进制。 0.1 是 1/10,不能用有限的二进制字符串表示。这是 1/16+1/32+ ...

所以 1/10 向下舍入,10 * 1/10 略小于 1。

至于第一种和第二种情况的结果不同,这可能是因为中间值被四舍五入的位数比double的位数多。

【讨论】:

  • 好的,我明白了。但为什么它会在第二种情况下失败,而不是在第一种情况下呢?
  • @Jumer - 生成汇编代码并查看差异。基本上,即使您在程序的另一部分执行相同的操作,也无法保证浮点数的准确性如何。见这里:parashift.com/c++-faq/floating-point-arith2.html
【解决方案2】:

如果要将接近整数的double 转换为int,请始终将值四舍五入为最接近的整数,例如使用round(),在将值转换为int 之前,因为doubleint 的转换会截断值,如果错误为负数,则会产生不正确的结果。

【讨论】:

    【解决方案3】:

    您正在遭受浮点运算固有的不准确性。在 0.1 的情况下,您可能得到的是 10.999.... 而不是 11。将 double 转换为 int 会截断而不是舍入,因此您会得到 10。在转换为 int 之前添加一个小值来解决这个问题。

    int size=operation+0.0000000001;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 2018-11-12
      • 1970-01-01
      • 1970-01-01
      • 2019-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多