C:如何将2 32位无符号整数的结果保存为有符号整数

我有以下代码将结果保存为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).

点赞