乘以1.0和int的精度浮点转换

假设条件(int)(i * 1.0f) == i对于任何整数i是否为真是安全的?

没有。

如果i足够大,那么int(float(i)) != i (假设float是IEEE-754单精度, i = 0x1000001就足够了),那么这是错误的,因为乘以1.0f强制转换为float ,即使后面的乘法没有改变值。

但是,如果i是一个32位整数和double是IEEE-754双,那么这真的, int(i*1.0) == i


为了完全清楚,乘以1.0f 确切的。 这是从intfloat的转换,可能不是。

不, IEEE-754浮点数在整数精度的代价下具有比整数更大的dynamic范围。

看例如这个小片段的输出:

 int main() { int x = 43046721; float y = x; printf("%d\n", x); printf("%f\n", y); } 

43046721不能在32位float的24位精度中正确表示,所以输出是沿着这些行的东西:

 43046721 43046720.000000 

事实上,我希望16,777,216以上的奇数在转换为32位float时有相同的问题。

几点兴趣:

  • 这与隐式的int-to-float转换有关,而不是乘法本身。

  • 这对C来说并不是什么特别的意思,比如说Java也受到同样的问题。

  • 大多数编译器有优化选项,可能会影响如何处理这种转换,忽略标准的某些限制。 在这种情况下,如果编译器将转换优化为float和back, (int)((float)x * 1.0f) == x可能总是为true

不,行为是实现定义的,因为C和C ++不需要IEEE-754,尽pipe这是迄今为止最常见的表示。

为了确保使用IEEE-754:

  • 在C中,使用#ifdef __STDC_IEC_559__
  • 在C ++中,使用std::numeric_limits<float>::is_iec559常量

不,这是所有的整数,因为types铸造是绝对错误的。 检查代码。

 #include <stdio.h> int main() { int i = 0; for (; i < 2147483647; ++i) { if ((int)(i * 1.0f) != i) { printf("not equal\n"); break; } } printf("out of the loop\n"); getchar(); return 0; } 

此代码假定您采取32位整数