gpt4 book ai didi

类型转换负数

转载 作者:太空狗 更新时间:2023-10-29 15:36:12 24 4
gpt4 key购买 nike

我正在尝试解释十六进制字节并将它们合并为有用的信息。

void processData(){
signed char data;
unsigned long a;//holds four bytes
unsigned long b;
unsigned int c;//holds two bytes
unsigned char d;//holds one byte

a=readA();//readA,readB,readC,readD return one unsigned byte;
b=readB();
c=readC();
d=readD();

data=(signed char) ((0xffffffff-((a<<24)|(b<<16)|(c<<8)|(d)))/1000);

}

场景是收到的整个包包含一个四字节的信息,例如一个值0xAABBCCDD。 readA() 将返回包中的最高字节,即 0xAA。 readD() 将返回 0xDD。所以我需要在使用“|”之前移动它们将它们放在一起:(a<<24)|(b<<16)|(c<<8)|(d)

所以我的问题是,对于这句话的右边

data=(signed char) ((0xffffffff-((a<<24)|(b<<16)|(c<<8)|(d)))/1000);

为什么当我将结果转换为带符号的字符时它不返回字符?当我打印出来时,一切都是错误的。但是,如果我设置 data as signed long,一切都是正确的。我猜这是因为 signed char 不够大,无法容纳所有信息并导致溢出。

如果我错了请纠正我,((a<<24)|(b<<16)|(c<<8)|(d))) 中的变量将全部隐式转换为 unsigned long,此表达式的结果也是如此。 ((a<<24)|(b<<16)|(c<<8)|(d)))/1000还将返回一个无符号长数。然而,结果将明显变小,因为它被除以 1000。

四字节信息的范围是0xFFFF5037到0xFFFFFFFF,也是这个表达式((a<<24)|(b<<16)|(c<<8)|(d)))的结果范围.

所以在除法完成后,表达式的右边应该在 0 到 45 之间。但是当我打印结果时,它都在跳来跳去。

最佳答案

6.3.1.3 有符号和无符号整数

1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged. 2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. 3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

您提供给我们的代码可能会以不同的方式运行,具体取决于我们使用的实现所做的选择。看到一个实现引发一个与异常条件相对应的实现定义的信号并不是没有道理的,例如 SIGSEGV。如果实现决定默认操作是忽略该信号,那么您就处于该实现的未定义行为领域。

在较长的类型中进行计算,然后将较长的值转换为较小的值,方法是将其以正确的宽度为模减小,并在必要时添加到 SCHAR_MIN 以产生负值。 (阅读评论)

void processData(){
signed char data;
unsigned long a; // holds sizeof (unsigned long) bytes*
unsigned long b;
unsigned int c; // holds sizeof (int) bytes*
unsigned char d; // holds one byte
// Footnote: int and unsigned long might have padding bits
// --------- Attempting to modify those padding bits can
// result in undefined behavior...

a = (readA() << 24) + (readB() << 16) + (readC() << 8) + d;
a /= 1000;

a %= UCHAR_MAX;
if (a <= SCHAR_MAX) {
// the value will fit safely into data as per point 1 of 6.3.1.3
data = a;
}
else if (a >= (unsigned char) SCHAR_MIN) {
// Since converting negative values to positive values will result
// in values greater than or equal to (unsigned char) SCHAR_MIN,
// by reducing a modulo
// (unsigned char) SCHAR_MIN we work out how many to add to SCHAR_MIN.
data = SCHAR_MIN + (a % (unsigned char) SCHAR_MIN);
}
else {
// The value is out of range. Perhaps it corresponds to a negative zero?
data = 0;
}
}

最后一个条件链可以缩短为:

data = a <= SCHAR_MAX                 ? a
: a >= (unsigned char) SCHAR_MIN? SCHAR_MIN +(a % (unsigned char) SCHAR_MIN)
: 0;

关于类型转换负数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15825430/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com