我如何制作输出NOT(x)的程序?
例子:
- 12到3
- 0到1
- 2比1
解释:
- 1100 至 0011
- 0到1
01 至 10
printf("%i\n%i\n%i\n", ~12, ~0, ~2);
印刷:
-13
-1
-3
printf("%i\n%i\n%i\n", !12, !0, !2);
印刷:
0
1
0
我如何制作输出NOT(x)的程序?
例子:
解释:
01 至 10
printf("%i\n%i\n%i\n", ~12, ~0, ~2);
印刷:
-13
-1
-3
printf("%i\n%i\n%i\n", !12, !0, !2);
印刷:
0
1
0
您对 printf 的可变参数被提升为int
,将其视为首先将您的位存储在变量中(int),然后对它们执行位而不是:
int x = 12; // 0x0000000C
int y = ~x; // 0xFFFFFFF4
y 现在是负符号 int 值。
将您的格式字符串和值更改为无符号,它可能更接近您正在寻找的内容:
int main(int argc, char *argv[])
{
unsigned int x = 12;
unsigned int y = ~x;
printf("%u:%u\n",x,y);
return EXIT_SUCCESS;
}
结果:
12:4294967283
如果您正在寻找打印值的实际“位”的功能,可以在这里找到一个很好的起点,因为 printf() 没有本机位二进制打印功能。
最后,如果您对翻转感兴趣的只是最重要的非零位,请务必在输入值为零 (0) 时对您的情况进行特殊处理。你真的需要一个“这么多位对我来说很重要”的价值来真正做到这一点。
编辑:一个非常低效的位串:显然,如果没有数字类型 作为前导模板参数,这将不起作用。自行决定使用(和危险)。
template<typename T, size_t N=sizeof(T)*8>
std::string bit_string(T value, size_t maxbits=N)
{
static const char *one = "1";
static const char *zero = "0";
std::string result;
maxbits = std::min(maxbits, N);
for (size_t i=0;i<maxbits;i++)
{
result = ((value & T(1)) ? one : zero) + result;
value >>= 1;
}
return result;
}
您的第一个示例之所以如此工作,是因为负数的二进制补码二进制表示法。
例如,该值12
实际上将表示为0000000000001100
一个 16 位整数,并且很可能实际上是一个 32 位整数。这个值的位非是1111111111110011
,这是-13
二进制补码。
您的第二个示例代码使用布尔非运算符。C++ 将任何非零值视为真,而“非真”的值始终false
为 或整数0
。同样,!0
表示“非假”并将-1
作为 C++ 的“标准真”值返回。(使用此值是因为!0 == -1
在二进制补码中,所以!false
和~false
是等价的操作。)
所以:你打算做的事情比你想象的要复杂。您所说的“NOT(x)”实际上是“二进制数的按位非,截断为有效数字的最小数量,并解释为无符号数。” 这并不像你说的那么简单!
有效数字部分尤为重要。如果所有数字都是 8 位无符号数,则 "NOT(2)" 实际上253
不是(如您所说)1
。
有趣的是,您的定义意味着 NOT 不再可逆:NOT(NOT(12))
is not 12
,但实际上会NOT(12) = 3
and then NOT(3) =
0
。
所以,为了实现你想要的:
sd
供稍后使用。)2 ^ (sd) - 1
例如,使用数字12
:
4
(2 ^ 4 = 16)1111111111110011
2 ^ 4 - 1 = 15
二进制是0000000000001111
1111111111110011 AND 0000000000001111 == 0000000000000011
这就是你想要的结果。好吧,如果你想翻转 int 中的所有位,你可以从 中减去值int max
,或者翻转一个短,从short max
... 至少我认为这就是你要问的。