如果没有像 Peter 提到的比较运算符,您无法将 1 或 0 转换为 bool。在没有比较运算符的情况下仍然可以得到max。
为了避免混淆,我使用 bit(1 或 0)而不是 int。
bit msb(x):
return lsb(x >> 31)
bit lsb(x):
return x &1
// returns 1 if x < 0, 0 if x >= 0
bit isNegative(x):
return msb(x)
有了这些助手isGreater(a, b) 看起来像,
// BUG: bug due to overflow when a is -ve and b is +ve
// returns 1 if a > b, 0 if a <= b
bit isGreater_BUG(a, b):
return isNegative(b - a) // possible overflow
我们需要两个辅助函数来检测相同和不同的标志,
// toggles lsb only
bit toggle(x):
return lsb(~x)
// returns 1 if a, b have same signs (0 is considered +ve).
bit isSameSigns(a, b):
return toggle(isDiffSigns(a, b))
// returns 1 if a, b have different signs (0 is considered +ve).
bit isDiffSigns(a, b):
return msb(a ^ b)
所以随着溢出问题的修复,
// returns 1 if a > b, 0 if a <= b
bit isGreater(a, b):
return
(isSameSigns(a, b) & isNegative(b - a)) |
(isDiffSigns(a, b) & isNegative(b))
请注意,isGreater 也适用于输入 5, 0 和 0, -5。
正确实施isPositive(x) 是棘手,因为0 也将被视为积极的。因此,不是使用上面的isPositive(a - b),而是使用isNegative(b - a),因为isNegative(x) 对0 有效。
现在 max 可以实现为,
// BUG: returns 0 when a == b instead of a (or b)
// returns a if a > b, b if b > a
int max_BUG(a, b):
return
isGreater(a, b) * a + // returns 0 when a = b
isGreater(b, a) * b //
要修复使用了isZero(x) 的帮助器,
// returns 1 if x is 0, else 0
bit isZero(x):
// x | -x will have msb 1 for a non-zero integer
// and 0 for 0
return toggle(msb(x | -x))
因此,当a = b 进行修复时,
// returns 1 if a == b else 0
bit isEqual(a, b):
return isZero(a - b) // or isZero(a ^ b)
int max(a, b):
return
isGreater(a, b) * a + // a > b, so a
isGreater(b, a) * b + // b > a, so b
isEqual(a, b) * a // a = b, so a (or b)
也就是说,如果 isPositive(0) 返回 1,那么 max(5, 5) 将返回 10 而不是 5。所以正确的 isPositive(x) 实现将是,
// returns 1 if x < 0, 0 if x >= 0
bit isPositive(x):
return isNotZero(x) & toggle(isNegative(x))
// returns 1 if x != 0, else 0
bit isNotZero(x):
return msb(x | -x)