使用运营商限制的代码质询的无效解决方案

时间:2017-09-23 14:06:40

标签: c++ c bit-manipulation bit-shift

要回答this question,我在github上阅读this source code,发现第二个功能有问题。

面临的挑战是编写C代码,在操作符和语言结构方面有各种限制来执行给定的任务。

BigInt

左移一个负值或一个移位值超出/* * fitsShort - return 1 if x can be represented as a * 16-bit, two's complement integer. * Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 8 * Rating: 1 */ int fitsShort(int x) { /* * after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111 * so after shift, if x remains the same, then it means that x can be represent as 16-bit */ return !(((x << 16) >> 16) ^ x); } 范围的数字有未定义的行为,右移一个负值是实现定义的,所以上面的解决方案是不正确的(虽然它可能是预期的溶液)。

这个问题的解决方案是否只假设32位二进制补码表示?

1 个答案:

答案 0 :(得分:1)

以下仅假设2位补码至少包含16位:

int mask = ~0x7FFF;
return !(x&mask)|!(~x&mask);

使用15位常数;如果它太大,你可以用三个较小的常量来构造它,但这会将它推到8个运算符限制之上。

一种等效的写作方式:

int m = 0x7FFF;
return !(x&~m)|!~(x|m);

但它仍然有7个操作,所以int m = (0x7F<<8)|0xFF;仍然会将它推到9.(我只是添加了它,因为我不认为我以前曾经使用过它!~。)