9

我面临将值从 Double 转换为 int 的问题。我尝试运行以下代码:

int main()
{
    double val_d= 6.25e-05;
    cout << (1/val_d) << endl;
    unsigned int val_ui = (unsigned int ) (1/val_d);
    cout << val_ui << endl;
}

从 double 到 int 的转换可能会删除小数部分,但整数部分应该保持原样?

我得到的输出是:16000 15999

那么为什么这里的 o/p 不同呢?这仅在 Fedora 上发生。在 Windows 和 Ubuntu 上运行良好。(两个输出都是16000)

我调整了上面的代码并得到了以下结果:

int main()
{
  double val_d= 6.25e-05;
  cout << (1/val_d) << endl;
  double val_intermediate =  (1/val_d) ;
  cout << val_intermediate << endl;
  unsigned int val_ui = (unsigned int ) val_intermediate;
  cout << val_ui << endl;

}

新输出为 16000 16000 16000

4

3 回答 3

16

当源文本“6.25e-05”被解释为十进制数字并转换为双精度时,它不能完全表示,因为浮点值的精度有限,并且每个位的值是 2 的幂,而不是一个十进制数字。最接近 6.25e-5 的 IEEE 754 双精度值是 6.25000000000000013010426069826053208089433610439300537109375e-05,或者十六进制浮点数为 0x1.0624dd2f1a9fcp-14。

当取其倒数时,精确的数学结果又不能完全表示,因此必须再次四舍五入。最接近的双精度值是 16000 或 0x1.f4p+13。

C++ 标准允许实现以比名义类型要求的精度更高的精度评估浮点表达式。一些实现使用扩展精度,特别是 Intel 的 80 位浮点类型,它具有 64 位有效位。(常规双精度有一个 53 位有效数。)在这个扩展精度中,倒数是 0xf.9ffffffffffffe89p+10 或 15999.999999999999966693309261245303787291049957275390625。

显然,当扩展精度结果被截断为整数时,结果为 15999。

将 long-double 结果四舍五入为 double 将产生 16000。(您可以通过显式强制转换为 double 来做到这一点;您不需要将中间值分配给 double 对象。)

于 2012-09-06T13:18:36.140 回答
6

四舍五入的差异。

  1. (1/val_d) - double 被四舍五入到可以用双精度表示的最接近的可能数字;(例如:3.6999999999999999 == 3.7)
  2. (unsigned int) (1/val_d) - 当转换为 int 小数部分被截断时,会导致四舍五入(例如:int(3.6) == 3
于 2012-09-06T11:33:55.203 回答
1

将浮点值转换为整数值会删除小数部分,前提是结果可以用整数类型表示(即该值不会太大而无法适应)。插入到流中会对值进行四舍五入,这可能会产生不同的结果。

于 2012-09-06T11:13:47.950 回答