数字类型之间的C ++转换究竟是如何工作的?

时间:2014-03-26 05:28:04

标签: c++ casting double uint64

在我的代码中,我执行以下操作:

double a = 3.0;
uint64_t b = static_cast<uint64_t>(a);
double c = static_cast<double>(b);

有趣的是,这可以像我期望的那样工作(a == c),只要a是正数,但如果a是负数,则c最终为任意大的正数。 (它必须包装在某处或某处。)

我的问题是:

  1. 为什么会这样?
  2. 为什么这段代码没有违反严格的别名规则?
  3. 注意: double和uint64_t在我的系统上大小相同。

2 个答案:

答案 0 :(得分:3)

严格的别名只会与指针一起发挥作用。在将double *转换为uint64_t *并通过该指针访问内存时,您不必在此担心。请阅读What is the strict aliasing rule?上的优秀答案,了解更多相关信息。

同样,对于转化,它会尝试将double所持有的值转换为uint64_t可表示的值。但是uint64_t是无符号的并且无法表示负值,因此当您尝试转换负值时,您会得到未定义的行为(也是正值过高且无法正确的值代表)。在实践中,你可能会得到一些高正数,但你不应该依赖它。


  

C ++标准版(N3797)4.9 [conv.fpint]/1说:

     
    

浮点类型的prvalue可以转换为a的prvalue     整数类型。转换截断;也就是说,小数部分     被丢弃了。如果截断值不能,则行为未定义     以目的地类型表示。 [注意:如果目的地     类型是bool,见4.12。 - 结束说明]

  

Chris Dodd在其评论中引用的定义仅适用于整数转换,而不适用于doubleuint64_t所依据的浮点转换。

答案 1 :(得分:0)

uint64_t表示64位无符号整数,因此当您转换为uint64_t时,如果该数字为负数,则会溢出,因为无符号整数不能存储负数。

尝试使用int64_t,它将按预期工作。