uint64_t如何存储负数? - 这不是意味着没有签名

时间:2012-03-11 15:23:50

标签: c++

  

可能重复:
  Signed to unsigned conversion in C - is it always safe?

uint64_t如何存储负数? - 这不是意味着没有签名或者我的代码是危险的吗?它是由侥幸工作的吗?

在代码中我为 uint64_t uint64_neg 分配一个负数(我希望负面,标志丢失)然后将uint64_t分配给int64_t但负面仍然存在 - 为什么这样好吗?

uint64_t uint64_neg = -150;

int64_t int64_neg = uint64_neg;

非常感谢。

2 个答案:

答案 0 :(得分:3)

标准中的第4.7节第3段(加上我强调):

  

如果目标类型已签名,则如果可以在目标类型(andbit-field width)中表示,则该值不会更改;否则,该值是实现定义的

也就是说,在编译器上,无符号到有符号转换只是“复制位”,在unsigned int中留下一些实现定义的值。这会在复制时溢出signed int的值,这恰好是在您的平台上定义的实现,以返回到相同的签名号码。

该标准不保证任何此类行为。

答案 1 :(得分:0)

比特是比特。发生了隐式转换。任何unsigned int都可以表示为signed int,只要它们的大小相同即可。当我第一次看到这个时,我感到困惑(这对于许多类型的编程来说并不常见),并且可能因编译器而异,所以在依赖它之前测试它。这里有一些代码演示如何使用字符使其易于理解:

#include <iostream>

int main()
{
    unsigned int u = 0;

    while ( u != 256 )
    {
       const signed char s = u;  // putting an unsigned type (u) into a signed type (s)

       // cast s up here so we don't print the extended ascii char.
       std::cout << (signed int)s << " signed == " << u << " unsigned" << std::endl;
       ++u;
    }

    return 0;
}

以下是该代码的一些输出:

-128 signed == 128 unsigned
-127 signed == 129 unsigned
-126 signed == 130 unsigned
...
-3 signed == 253 unsigned
-2 signed == 254 unsigned
-1 signed == 255 unsigned
如果你用这种方式初始化,那么C ++ 11编译器会产生一个缩小的错误:

unsigned int j = {-32768}; // Notice the brackets