由于已知整数是非负数,因此可以简单地将整数的所有位一一地或在一起。结果是所需的谓词。在源操作数用完之前执行按位 OR-ing 的简单循环需要比较,这是不允许的。
在我现在可以看到的强加限制下,唯一可行的替代方法是使用直线代码,该代码重复位提取过程的步骤与整数的位数一样多。这是我在下面的 ISO-C99 代码中使用的。每个位都是用 DIV 和 MOD 提取的。两个一位变量 s 和 t 的 OR 计算为 s + t - s * t。对 32 位整数进行简单的详尽测试,证实这种方法是可行的,但效率显然不是很高。
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define OR1(s,t) (s + t - s * t)
// (x >= 1) ? 1 : 0
uint32_t ge1 (uint32_t x)
{
uint32_t y;
y = OR1 (
OR1 (
OR1 (OR1 (OR1 ((x / 0x00000001) % 2, (x / 0x00000002) % 2),
OR1 ((x / 0x00000004) % 2, (x / 0x00000008) % 2)),
OR1 (OR1 ((x / 0x00000010) % 2, (x / 0x00000020) % 2),
OR1 ((x / 0x00000040) % 2, (x / 0x00000080) % 2))),
OR1 (OR1 (OR1 ((x / 0x00000100) % 2, (x / 0x00000200) % 2),
OR1 ((x / 0x00000400) % 2, (x / 0x00000800) % 2)),
OR1 (OR1 ((x / 0x00001000) % 2, (x / 0x00002000) % 2),
OR1 ((x / 0x00004000) % 2, (x / 0x00008000) % 2)))),
OR1 (
OR1 (OR1 (OR1 ((x / 0x00010000) % 2, (x / 0x00020000) % 2),
OR1 ((x / 0x00040000) % 2, (x / 0x00080000) % 2)),
OR1 (OR1 ((x / 0x00100000) % 2, (x / 0x00200000) % 2),
OR1 ((x / 0x00400000) % 2, (x / 0x00800000) % 2))),
OR1 (OR1 (OR1 ((x / 0x01000000) % 2, (x / 0x02000000) % 2),
OR1 ((x / 0x04000000) % 2, (x / 0x08000000) % 2)),
OR1 (OR1 ((x / 0x10000000) % 2, (x / 0x20000000) % 2),
OR1 ((x / 0x40000000) % 2, (x / 0x80000000) % 2)))));
return y;
}
int main (void)
{
uint32_t x, res, ref;
x = 0;
do {
res = ge1 (x);
ref = x >= 1;
if (res != ref) {
printf ("error: x=%08x res=%08x ref=%08x\n", x, res, ref);
return EXIT_FAILURE;
}
x++;
} while (x);
printf ("test passed\n");
return EXIT_SUCCESS;
}