我有以下代码将结果保存为32位有符号整数和64位有符号整数.
当我用2147483647(有符号32位整数的最大允许值)减去0时,使用32位有符号整数会导致问题,因此正确的方法应该是使用64位有符号整数,我应该将无符号32位强制转换为有符号64位来获取想要的答案.这是正确的方法吗?
#include <stdio.h>
#include <string.h>
#include <stdint.h>
int main(void)
{
int32_t fig32;
int64_t fig64;
uint32_t peak_seq = 2480694779;
uint32_t pkt_seq = 2480694780;
uint32_t zero_seq = 0;
fig32 = peak_seq - pkt_seq;
fig64 = peak_seq - pkt_seq;
printf("\n 32 ans : %d, 64 ans is %ld\n", fig32, fig64);
fig32 = zero_seq - pkt_seq;
fig64 = zero_seq - pkt_seq;
printf("\n 32 ans : %d, 64 ans is %ld\n", fig32, fig64);
fig64 = (int64_t)peak_seq - (int64_t)pkt_seq;
printf("\n fix for (peak - pkt) 64 ans is %ld\n", fig64);
fig64 = (int64_t)zero_seq - (int64_t)pkt_seq;
printf("\n fix for (zero - pkt) 64 ans is %ld\n", fig64);
}
当我运行这个程序时,我得到以下输出
32 ans : -1, 64 ans is 4294967295
32 ans : 1814272516, 64 ans is 1814272516
fix for (peak - pkt) 64 ans is -1
fix for (zero - pkt) 64 ans is -2480694780
>在第一行中为什么64位的答案是4294967295而不是
-1?
>是否将所有无符号32位整数强制转换为64位符号
唯一的办法解决这个问题?
最佳答案 首先,在任何C表达式x = y z;用于计算y z的类型与x的类型无关.任何计算中使用的类型取决于特定运算符的操作数的类型.
在您的情况下,用于计算peak_seq的类型 – pkt_seq与您在何处存储结果无关.由于两个操作数都是uint32_t类型(并且由于int在任何机器上可能不大于32位),因此操作在uint32_t类型上执行.结果是uint32_t类型.
由于操作的两个操作数都是无符号类型,因此它会下溢到4294967295.因此,此代码中的peak_seq – pkt_seq的结果始终为(uint32_t)4294967295,或者如果您将为0xFFFFFFFF.
In the first line why is the answer for 64 bit a 4294967295 and not -1 ?
当您尝试将此结果存储到int32_t中时,它会根据实现定义的行为进行转换,在这种情况下,您将获得0xFFFFFFFF的二进制补码版本-1.
但是当你尝试在int64_t中恢复结果时,它很合适并且值不会改变.
Is typecasting all the unsigned 32 bit integers to signed 64 bit the only way to solve this problem?
如果您需要签名号码,请使用签名号码.您发现代码结果奇怪的唯一原因是,如果您错误地认为两个无符号操作数将为您提供签名结果.
作为旁注,当打印int32_t时,你应该使用printf(“%”PRId,fig32),对于int64_t,使用PRId64(inttypes.h).