简体   繁体   English

C如何处理符号扩展?

[英]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_tint8_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM