具有操作员限制的代码挑战的无效解决方案
Invalid solution for code challenge with operator restrictions
在 github 上回答 , I read this source code,发现第二个函数有问题。
挑战在于编写在运算符和语言结构方面具有各种限制的 C 代码来执行给定任务。
/*
* 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);
}
左移负值或移位值超出int
范围的数字有未定义的行为,右移负值是实现定义的,所以上面的解决方案是不正确的(虽然它可能是预期的解决方案)。
是否有仅假设 32 位二进制补码表示的解决方案?
以下只假设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 次。(我添加它只是因为我认为我以前从未发现 !~
的用途。 )
在 github 上回答
挑战在于编写在运算符和语言结构方面具有各种限制的 C 代码来执行给定任务。
/*
* 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);
}
左移负值或移位值超出int
范围的数字有未定义的行为,右移负值是实现定义的,所以上面的解决方案是不正确的(虽然它可能是预期的解决方案)。
是否有仅假设 32 位二进制补码表示的解决方案?
以下只假设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 次。(我添加它只是因为我认为我以前从未发现 !~
的用途。 )