(int)4294967295.0 = 2147483647?

时间:2014-09-01 07:21:29

标签: c

示例代码:

#include <stdio.h>

int main() {
    printf("%d", (int)4294967295.0);
    return 0;
}

这会在键盘上打印2147483647(http://codepad.org/yDCqFdTT) 和我的vs2012设置-2147483648。预计-1。然而,正确地将4294967295.0转换为无符号整数会产生-1。

发生了什么?如何安全地将我的double转换为int?这种错误超出了舍入误差的范围。

3 个答案:

答案 0 :(得分:8)

根据草案N1256(C99)§6.3.1.4,您正在调用未定义的行为:

  

6.3.1.4实数浮点数和整数

     
      
  1. 当实数浮动类型的有限值被转换为除_Bool以外的整数类型时,小数部分被丢弃(即,该值被截断为零)。如果整数部分的值不能用整数类型表示,则行为是未定义的。 50)

  2.   
  3. 当整数类型的值转换为实际浮动类型时,如果要转换的值可以在新类型中准确表示,则它将保持不变。如果转换的值在可以表示但不能精确表示的值的范围内,则结果是以实现定义的方式选择的最接近的较高或最接近的较低可表示值。如果转换的值超出了可以表示的值范围,则行为未定义。

  4.         

    50)当将实数浮点类型的值转换为无符号类型时,不需要执行将整数类型的值转换为无符号类型时执行的剩余操作。因此,便携式实际浮动值的范围是(-1,Utype_MAX+1)。

答案 1 :(得分:0)

发生了什么是未定义的行为:将值转换为无法保留它的数字类型int

根据您的平台(如果int为32位),此值的整数部分太大而无法用unsigned int表示。任何事情都可能发生,因为标准明确告诉编译器/硬件可以做任何它喜欢的事情。

您可以使用类似boost::numeric_cast的内容来测试此类问题。

答案 2 :(得分:0)

从double到int的转换首先忽略小数部分,给出4294967295.这个数字在int类型中是不可表示的,因此结果是未定义的行为。结果可能是任何数字。您的计算机可能崩溃或爆炸。任何事情都可能发生,因为您的代码调用了未定义的行为。