C 如何处理符号扩展? [英] How does C handle sign extension?
问题描述
我有一个指向字节缓冲区的指针,从中我将每个偶数索引字节复制到一个 int(由于协议将数据存储到缓冲区中,我知道奇数周期用于读取).现在当我这样做
signed int a;...//在一个循环中a = 缓冲区[2*i];//缓冲区无符号
它给了我一个无符号数.但是当我这样做时
a = (int8_t)buffer[2*i]
数字以签名形式显示.这迫使我重新思考 c 中符号扩展的工作方式,尤其是在上述场景中.我的理解是,由于我将 a 声明为已签名,因此编译器将自动执行签名扩展.任何人都可以花一些时间来解释为什么情况并非如此.我刚刚在这个陷阱里呆了一个小时,以后不想再掉进这个陷阱了.
buffer
是一个无符号八位整数数组(或作为一个整数).所以 buffer[2*i]
的值在 0 到 255(含)的范围内,并且该范围内的所有值都可以表示为 int
s,因此赋值
a = buffer[2*i];
保留值,通过用零填充来提升到更广泛的类型int
.
如果在赋值之前转换为 int8_t
,
a = (int8_t)buffer[2*i]
缓冲区中大于 127 的值以实现定义的方式转换为类型 int8_t
,很可能只是将位模式重新解释为有符号的 8 位整数,这会导致负值,从 -128 到 -1.这些值可以表示为 int
s,因此它们在赋值中保留,然后通过符号扩展完成对更广泛类型 int
的值保留提升.>
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). 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. 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). 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
a = buffer[2*i];
preserves the value, the promotion to the wider type int
is done by padding with zeros.
If you cast to int8_t
before assigning,
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. 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.
这篇关于C 如何处理符号扩展?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!