[英]How does C handle sign extension?
I have a pointer to a buffer of bytes from which I am copying every even indexed bytes to an int(because of the protocol that the data is stored into buffer I know the odd cycles are for read). 我有一个指向字节缓冲区的指针,我将从中将每个偶数索引字节都复制到一个int(因为该协议将数据存储在缓冲区中,我知道奇数周期可供读取)。 Now when I do this
现在当我这样做
signed int a;
...
//inside a loop
a = buffer[2*i]; //buffer is unsigned
It gives me an unsigned number. 它给了我一个未签名的号码。 However when I do this
但是当我这样做时
a = (int8_t)buffer[2*i]
the number is presented in signed form. 数字以签名形式显示。 That is forcing me to rethink how sign extension in c work, especially in scenarios like above.
这迫使我重新考虑c中的符号扩展如何工作,尤其是在上述情况下。 My understanding was since I am declaring a as signed, compiler will automatically do the sign extension.
我的理解是,由于我声明为签名,因此编译器将自动进行符号扩展。 Can anybody take some time to explain why this is not the case.
任何人都可以花一些时间来解释为什么不是这种情况。 I just spent an hour in this trap and don't want to fall in the same trap in future again.
我在这个陷阱中呆了一个小时,不想以后再陷入同一陷阱。
buffer
is an array of unsigned eight-bit integers (or acts as one). buffer
是一个无符号八位整数数组(或充当一个整数)。 So the value of buffer[2*i]
is in the range from 0 to 255 (inclusive), and all values in that range are representable as int
s, so assigning 因此,
buffer[2*i]
值在0到255(包括)范围内,并且该范围内的所有值都可以表示为int
s,因此分配
a = buffer[2*i];
preserves the value, the promotion to the wider type int
is done by padding with zeros. 保留值,通过用零填充来提升为更大的类型
int
。
If you cast to int8_t
before assigning, 如果您在分配前
int8_t
为int8_t
,
a = (int8_t)buffer[2*i]
values in the buffer larger than 127 are converted in an implementation-defined way to type int8_t
, most likely by just reinterpreting the bit-pattern as a signed 8-bit integer, which results in a negative value, from -128 to -1. 大于127的缓冲区中的值将以实现定义的方式转换为
int8_t
类型,很可能是通过将位模式重新解释为带符号的8位整数,这导致从-128到-1的负值。 These values are representable as int
s, so they are preserved in the assignment, the value-preserving promotion to the wider type int
is then done by sign-extension. 这些值可以表示为
int
,因此将它们保留在赋值中,然后通过符号扩展将值保留提升为更广泛的类型int
。
An int_8 only has 8 bits, if the highest bit is 1 it holds a negative value : 1xxxxxxx , if you assign such a value to a signed int(32 or 64 bits), of course you would get a negative value. 一个int_8仅具有8位,如果最高位为1,则它具有负值:1xxxxxxx,如果将这样的值分配给有符号的int(32位或64位),则当然会得到一个负值。 the longer int would look like
11111111 11111111 11111111 1xxxxxxx
after the assignment, just a simple xor would do the trick 00000000 ^ 1001 => 11111001. 赋值后,较长的int看起来像
11111111 11111111 11111111 1xxxxxxx
,只是一个简单的xor就可以完成技巧00000000 ^ 1001 => 11111001。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.