C语言 在 C 中将 int 转换为 short
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18276225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
convert int to short in C
提问by user1128265
I have:
我有:
int a = 2147483647;
short b = (short)a;
and I get b = -1whereas I expect int32to be converted to int16(short). I expect to see some value and not-1.
我得到了,b = -1而我希望int32被转换为int16( short)。我希望看到一些价值而不是-1.
Please someone help me with this.
请有人帮我解决这个问题。
采纳答案by Magn3s1um
Your int A is larger than the size of short. When you convert A to short, you get a 1 in the left most bit, which is going to indicate that it is a negative number. Since you're getting -1, I suppose you're getting 1s in all 16 bits, which is going to give you -2^15 + 2^14 + 2^13... + 2^0, which will give you -1. In short (no pun intended), you can't convert the integer to a short if it is too large.
您的 int A 大于 short 的大小。当您将 A 转换为 short 时,您会在最左边的位中得到一个 1,这表示它是一个负数。既然你得到 -1,我想你在所有 16 位都得到 1,这会给你 -2^15 + 2^14 + 2^13 ... + 2^0,这会给你-1. 简而言之(没有双关语),如果整数太大,则不能将整数转换为短整数。
回答by dasblinkenlight
The value 2147483647, or 231-1 overflows a 16-bit integer. Its binary representation is zero in the MSB followed by 31 ones in the remaining bits.
值 2147483647 或 2 31-1 溢出一个 16 位整数。它的二进制表示在 MSB 中是 0,其余位中是 31 个 1。
It looks like in your implementation the last 16 bits are taken in the conversion to short. When this happens, all of them are set to 1, resulting in a 2's complementrepresentation of -1:
看起来在您的实现中,最后 16 位是在转换为short. 发生这种情况时,所有这些都设置为1,从而产生2 的补码表示-1:
32-bit int: 01111111111111111111111111111111
16-bit short: ----------------1111111111111111
However, neither the 2-compliment representation nor this behavior in general is part of the C++ standard, so this behavior is implementation-defined.
但是,无论是 2-compliment 表示还是一般的这种行为都不是 C++ 标准的一部分,所以这种行为是实现定义的。
回答by Keith Thompson
Converting a value to a signedtype, when the source value doesn't fit in the target type, yield an implementation-definedresult. That means that any conforming compiler's documentation must document what that result is.
将值转换为有符号类型,当源值不适合目标类型时,会产生实现定义的结果。这意味着任何符合标准的编译器文档都必须记录该结果是什么。
(This is unlike the behavior on overflow of an arithmetic operator. For example:
(这与算术运算符溢出时的行为不同。例如:
int overflow = INT_MAX + 1;
actually has undefined behavior. But in either case, you should be careful to write your code so it doesn't trigger this kind of problem.)
实际上有未定义的行为。但无论哪种情况,您都应该小心编写代码,以免触发此类问题。)
For many implementations, for both conversion and arithmetic, an overflow where the target is an N-bit type simply takes the N low-order bits of the correct result.
对于许多实现,对于转换和算术,目标为 N 位类型的溢出仅采用正确结果的 N 个低位。
In your case, apparently intis 32 bits and shortis 16 bits (those sizes can vary on different implementations). 2147483647is 0x7fffffff, the low-order 16 bits are 0xffff, which is (again, on your implementation) the representation of -1in type short.
在您的情况下,显然int是 32 位和short16 位(这些大小可能因不同的实现而异)。2147483647is 0x7fffffff,低 16 位是0xffff,这是(同样,在您的实现中)-1in type的表示short。
For conversion to unsigned types, the result is strictly defined by the standard; it takes the low-order N bits of the result. And for overflowing floating-point conversion (say, converting a very large doublevalue to float), the behavior is undefined.
对于无符号类型的转换,结果由标准严格定义;它取结果的低 N 位。对于溢出浮点转换(例如,将非常大的double值转换为float),行为未定义。
So far, this is all the same for C and C++. But just to add to the confusion, starting with the 1999 standard an overflowing signed conversion is permitted to raise an implementation-defined signal. C++ doesn't have this. I don't know of any compiler that actually does this.
到目前为止,这对于 C 和 C++ 都是一样的。但更令人困惑的是,从 1999 年标准开始,允许溢出有符号转换来引发实现定义的信号。C++没有这个。我不知道任何实际执行此操作的编译器。
I expect to see some value and not
-1.
我希望看到一些价值而不是
-1.
-1is"some value". Was there some specific value you expected?
-1是“一些价值”。是否有您期望的特定值?
Incidentally:
顺便:
short b = (short)a;
The cast is unnecessary. Assignment, initialization, parameter passing, and returnstatements can assign values between any numeric types without a cast. The value is converted implicitly:
演员表是不必要的。赋值、初始化、参数传递和return语句可以在没有强制转换的情况下在任何数字类型之间赋值。该值被隐式转换:
short b = a;
回答by Shafik Yaghmour
This is implementation definedbehavior, for example gccIntegers Implementation documentsays:
这是implementation defined行为,例如gccIntegers Implementation document说:
For conversion to a type of width N, the value is reduced modulo 2^N to be within rangeof the type; no signal is raised.
转换为宽度为 N 的类型,该值以2^N 为模减少到类型的范围内;没有发出信号。
This can differ from compiler to compiler, I am not able to dig up similar documents for clangnor visual studio.
这可能因编译器而异,我无法为clangnor挖掘类似的文档visual studio。
From the draft C++ standard, section 4.7 Integral conversionsparagraph 3:
从 C++ 标准草案,部分4.7 Integral conversions段落3:
If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.
如果目标类型是有符号的,如果它可以在目标类型(和位域宽度)中表示,则该值不变;否则,该值为 implementation-defined。
If this was unsignedthen you would have perfectly well defined behavior, as per paragraph 2:
如果是这样,unsigned那么您将拥有完美定义的行为,根据段落2:
If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [ Note: In a two's complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]
如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2n,其中 n 是用于表示无符号类型的位数)。[ 注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。——尾注]
The language is similar in the C99draft standard section 6.3.1.3 Signed and unsigned integers.
C99标准草案部分中的语言类似6.3.1.3 Signed and unsigned integers。
回答by edW
You can do this:
你可以这样做:
uint32_t sum=0xFFFF1234;
uint16_t *p= (uint16_t *) ∑
uint16_t checksum=p[0];
check-sum is 0x1234.
校验和是0x1234。
Here is another way:
这是另一种方式:
union ToShort
{
uint32_t sum;
uint16_t checksum[2];
} toShort;
toShort.sum=0xFFFF1234;
cout << hex << toShort.checksum[0];
output is 1234.
输出是1234。

