将int转换为C中的short

use*_*265 9 c int short

我有:

int a = 2147483647;
short b = (short)a;
Run Code Online (Sandbox Code Playgroud)

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

请有人帮我这个.

das*_*ght 23

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

看起来在您的实现中,转换为最后16位short.当发生这种情况时,所有这些都被设置为1,导致2的补码表示-1:

32-bit int:   01111111111111111111111111111111
16-bit short: ----------------1111111111111111
Run Code Online (Sandbox Code Playgroud)

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

  • @EricPostpischil:行为未定义; 结果是实现定义的,这意味着实现必须记录它. (7认同)
  • @EricPostpischil:n3690第80页4.7(1)说它是实现定义的,而不是未定义的.不确定一个实现是否可以自由地将其定义为未定义的行为,但是:-) (2认同)

Kei*_*son 11

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

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

int overflow = INT_MAX + 1;
Run Code Online (Sandbox Code Playgroud)

实际上有未定义的行为.但在任何一种情况下,您都应该小心编写代码,这样就不会触发这类问题.)

对于许多实现,对于转换和算术,目标是N位类型的溢出只是获取正确结果的N个低位.

在您的情况下,显然int是32位并且short是16位(这些大小可以根据不同的实现而变化).21474836470x7fffffff,低16位0xffff,(再次,在您的实现)的-1类型的表示short.

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

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

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

-1 "有些价值".你有什么特定的价值吗?

偶然:

short b = (short)a;
Run Code Online (Sandbox Code Playgroud)

演员是不必要的.赋值,初始化,参数传递和return语句可以在没有强制转换的情况下在任何数字类型之间分配值.该值隐式转换:

short b = a;
Run Code Online (Sandbox Code Playgroud)


Sha*_*our 8

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

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

这可以从编译器编译器不同,我不能挖了类似文件的clang,也没有visual studio.

从草案C++标准,部分4.7 Integral conversions段落3:

如果目标类型已签名,则如果可以在目标类型(和位字段宽度)中表示该值,则该值不会更改; 否则,该值是实现定义的.

如果是这样的unsigned话你会有完全明确的行为,按照段落2:

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

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


Mag*_*1um 6

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