具有操作员限制的代码挑战的无效解决方案

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 次。(我添加它只是因为我认为我以前从未发现 !~ 的用途。 )