gpt4 book ai didi

c - 无符号整数减法是否定义了行为?

转载 作者:太空狗 更新时间:2023-10-29 16:14:56 26 4
gpt4 key购买 nike

我遇到过一些人的代码,他们似乎认为在结果为负时从另一个相同类型的整数中减去一个无符号整数会出现问题。所以这样的代码即使适用于大多数架构也是不正确的。

unsigned int To, Tf;

To = getcounter();
while (1) {
Tf = getcounter();
if ((Tf-To) >= TIME_LIMIT) {
break;
}
}

这是我能找到的 C 标准中唯一模糊相关的引用。

A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

我想人们可以将这句话理解为当右操作数较大时,操作被调整为在模截断数字的上下文中有意义。

0x0000 - 0x0001 == 0x 1 0000 - 0x0001 == 0xFFFF

与使用依赖于实现的签名语义相反:

0x0000 - 0x0001 ==(无符号)(0 + -1)==(0xFFFF 还有 0xFFFE 或 0x8001)

哪种解释是正确的?它有定义吗?

最佳答案

当您使用unsigned 类型时,modular arithmetic (也称为 “环绕” 行为)正在发生。要理解这种模运算,只需看看这些时钟:

enter image description here

9 + 4 = 1 (13 mod 12),所以到另一个方向是:1 - 4 = 9 (< em>-3 模 12)。在处理无符号类型时应用相同的原则。如果结果类型unsigned,则进行模运算。


现在看看以下将结果存储为 unsigned int 的操作:

unsigned int five = 5, seven = 7;
unsigned int a = five - seven; // a = (-2 % 2^32) = 4294967294

int one = 1, six = 6;
unsigned int b = one - six; // b = (-5 % 2^32) = 4294967291

当你想确保结果是signed时,将其存储到signed变量或将其转换为signed。当您想获得数字之间的差异并确保不应用模运算时,您应该考虑使用 abs() stdlib.h 中定义的函数:

int c = five - seven;       // c = -2
int d = abs(five - seven); // d = 2

要非常小心,尤其是在编写条件时,因为:

if (abs(five - seven) < seven)  // = if (2 < 7)
// ...

if (five - seven < -1) // = if (-2 < -1)
// ...

if (one - six < 1) // = if (-5 < 1)
// ...

if ((int)(five - seven) < 1) // = if (-2 < 1)
// ...

但是

if (five - seven < 1)   // = if ((unsigned int)-2 < 1) = if (4294967294 < 1)
// ...

if (one - six < five) // = if ((unsigned int)-5 < 5) = if (4294967291 < 5)
// ...

关于c - 无符号整数减法是否定义了行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7221409/

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