我有一个有趣的谜题。我需要将有符号数(例如 -5 (0x80000005))转换为二进制补码 -5 (0xFFFFFFFB)。我唯一可以使用的运算符是 !、~、&、^、|、+、<<、>> 以及最多 15 个运算符与我想要的任意数量的变量的任意组合。 = 可以使用,但不计入运算符总数。此外,不得使用“if”语句、循环或调用任何类型的函数。
函数看起来像
int sign2two(int x){
//... some stuff here
return x;
}
我遇到的问题是我可以查明数字是否为负数。但我想说,如果 num 为负数,则翻转位并加 1。否则返回数字。我不知道该怎么做。谢谢。
最佳答案
这些问题在我看来是极其愚蠢的...
#include <stdint.h>
#include <stdio.h>
int32_t test1(uint32_t x) {
const uint32_t sign = (x & 0x80000000); // Total operations: 1
const uint32_t value = (x & 0x7FFFFFFF); // Total operations: 2
// Let's create a value N, where N is equal to:
// if (sign)
// N = 0xFFFFFFFF;
// else
// N = 0x00000000;
uint32_t N = sign; // Total operations: 2
N = N | (N >> 1); // Total operations: 4
N = N | (N >> 2); // Total operations: 6
N = N | (N >> 4); // Total operations: 8
N = N | (N >> 8); // Total operations: 10
N = N | (N >> 16); // Total operations: 12
// Let's create a value MaybeOne, where MaybeOne is equal to:
// if (sign)
// MaybeOne = 1;
// else
// MaybeOne = 0;
uint32_t MaybeOne = N & 0x1; // Total operations: 13
// Now, Let's perform the following step:
// if (sign)
// return (value ^ 0xFFFFFFFF) + 1;
// else
// return (value ^ 0x00000000) + 0;
return (value ^ N) + MaybeOne; // Total operations: 15
}
int32_t test2(uint32_t x) {
int32_t sign = (x & 0x80000000);
int32_t value = (x & 0x7FFFFFFF);
if (sign)
return -value;
else
return value;
}
int main() {
uint32_t i;
for (i=0; i<0xFFFFFFFF; ++i)
if (test1(i) != test2(i))
printf("0x%08x\n", i);
}
此外,使用来自 Eric Postpischil 的评论,我们可以显着减少操作次数:
int32_t test3(uint32_t x) {
const uint32_t sign = (x >> 31); // Total operations: 1
const uint32_t value = (x & 0x7FFFFFFF); // Total operations: 2
// Let's create a value N, where N is equal to:
// if (sign)
// N = 0xFFFFFFFF;
// else
// N = 0x00000000;
const uint32_t N = ~sign + 1; // Total operations: 4
// Let's create a value MaybeOne, where MaybeOne is equal to:
// if (sign)
// MaybeOne = 1;
// else
// MaybeOne = 0;
uint32_t MaybeOne = sign; // Total operations: 4
// Now, Let's perform the following step:
// if (sign)
// return (value ^ 0xFFFFFFFF) + 1;
// else
// return (value ^ 0x00000000) + 0;
return (value ^ N) + MaybeOne; // Total operations: 6
}
关于c - 在二进制中,从有符号数转换为二进制补码。全部在 C 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21918419/