《Modern C》中无符号模拟有符号整数比较代码是否存在错误?
《Modern C》中无符号模拟有符号整数比较代码的问题分析
Jens Gustedt所著《Modern C》第59页给出了一段用无符号整数模拟有符号整数比较逻辑的代码:
bool is_negative(unsigned a) { unsigned const int_max = UINT_MAX /2; return a > int_max; } bool is_signed_less(unsigned a, unsigned b) { if (is_negative(b) && !is_negative(a)) return false; else return a < b; }
你观察得完全正确,这段代码确实遗漏了**is_negative(a)=true且is_negative(b)=false**的特殊情况,导致比较结果错误。
比如你举的补码示例:a=-1的无符号表示为UINT_MAX(4位整数下是1111),b=1的无符号表示为1(4位整数下是0001)。此时is_negative(a)返回true,is_negative(b)返回false,调用is_signed_less(a,b)会进入else分支,按无符号规则比较a < b返回false,但实际有符号比较中-1 < 1,结果明显不符合预期。
这段代码的逻辑仅处理了b为负、a为正的情况(此时正整数不可能小于负整数,直接返回false),但完全忽略了a为负、b为正的场景——这种情况下有符号比较的结果必然是true(负整数一定小于正整数),原代码直接走无符号比较的逻辑,显然不符合需求。
修正后的完整逻辑需要覆盖所有符号组合:
bool is_negative(unsigned a) { unsigned const int_max = UINT_MAX / 2; return a > int_max; } bool is_signed_less(unsigned a, unsigned b) { bool a_neg = is_negative(a); bool b_neg = is_negative(b); if (a_neg && !b_neg) { return true; // 负整数必然小于正整数 } else if (!a_neg && b_neg) { return false; // 正整数不可能小于负整数 } else { return a < b; // 同符号时,补码下无符号比较结果与有符号一致 } }
内容的提问来源于stack exchange,提问作者JezuzStardust
相关产品推荐
相关产品推荐

