12

我有:

int a = 2147483647;
short b = (short)a;

我得到了b = -1,而我希望int32被转换为int16short)。我希望看到一些价值而不是 -1.

请有人帮我解决这个问题。

4

5 回答 5

24

值 2147483647 或 2 31 -1 溢出 16 位整数。它的二进制表示在 MSB 中为零,其余位中为 31 个 1。

看起来在您的实现中,最后 16 位被转换为short. 发生这种情况时,它们都设置为1,从而产生 的2 的补码表示-1

32-bit int:   01111111111111111111111111111111
16-bit short: ----------------1111111111111111

但是,2-compliment 表示和这种行为通常都不是 C++ 标准的一部分,因此这种行为是实现定义的。

于 2013-08-16T14:57:21.377 回答
11

将值转换为有符号类型,当源值不适合目标类型时,会产生实现定义的结果。这意味着任何符合标准的编译器的文档都必须记录结果是什么。

(这与算术运算符溢出时的行为不同。例如:

int overflow = INT_MAX + 1;

实际上有未定义的行为。但无论哪种情况,您都应该小心编写代码,以免引发此类问题。)

对于许多实现,对于转换和算术来说,目标是 N 位类型的溢出只需要正确结果的 N 个低位。

在您的情况下,显然int是 32 位和short16 位(这些大小可能因不同的实现而异)。21474836470x7fffffff,低 16 位是0xffff,这是(同样,在您的实现中)-1in 类型的表示short

对于转换为无符号类型,结果由标准严格定义;它取结果的低 N 位。对于溢出的浮点转换(例如,将一个非常大的double值转换为float),行为是未定义的。

到目前为止,这对于 C 和 C++ 来说都是一样的。但只是为了增加混乱,从 1999 年标准开始,允许溢出的有符号转换来引发实现定义的信号。C++ 没有这个。我不知道实际上有任何编译器可以做到这一点。

我希望看到一些价值而不是 -1.

-1 “一些价值”。有没有你期望的特定价值?

顺便:

short b = (short)a;

演员阵容是不必要的。赋值、初始化、参数传递和return语句可以在任何数字类型之间赋值,而无需强制转换。该值被隐式转换:

short b = a;
于 2013-08-16T15:34:20.337 回答
9

这是implementation defined行为,例如gcc Integers Implementation document说:

为了转换为宽度为 N 的类型,该值以2^N 为模减少到该类型的范围内;没有发出信号。

这可能因编译器而异,我无法为clangnor挖掘类似的文档visual studio

来自 C++ 标准草案,段落4.7 Integral conversions段落3

如果目标类型是有符号的,则如果它可以在目标类型(和位域宽度)中表示,则该值不变;否则,该值是实现定义的

如果是这样unsigned,那么根据段落,您将拥有完美定义的行为2

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2n,其中 n 是用于表示无符号类型的位数)。[ 注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。——尾注]

C99标准草案部分的语言类似6.3.1.3 Signed and unsigned integers

于 2013-08-16T15:10:07.473 回答
8

您的 int A 大于 short 的大小。当您将 A 转换为 short 时,您会在最左边得到一个 1,这将表明它是一个负数。因为你得到 -1,我想你在所有 16 位中得到 1,这将给你 -2^15 + 2^14 + 2^13... + 2^0,这会给你-1。简而言之(没有双关语),如果整数太大,则无法将整数转换为短整数。

于 2013-08-16T14:56:59.797 回答
4

你可以这样做:

uint32_t sum=0xFFFF1234;
uint16_t *p= (uint16_t *) ∑
uint16_t checksum=p[0]; 

校验和是0x1234

这是另一种方式:

union ToShort
{
        uint32_t sum;
        uint16_t checksum[2];
} toShort;
toShort.sum=0xFFFF1234;
cout << hex << toShort.checksum[0];

输出是1234

于 2014-02-26T19:36:41.467 回答