使用 C 中的按位运算符检查数字是否非零
使用除 !
之外的合法运算符检查数字 x
是否非零。
示例:isNonZero(3) = 1
、isNonZero(0) = 0
合法操作:~
&
< code>^ |
+
<<
>>
- 注意:仅限位运算符应该使用。不能使用
if
、else
、for
等。 - Edit1:运算符数量不应超过 10。
- Edit2:将
int
的大小视为 4 个字节。
int isNonZero(int x) {
return ???;
}
使用 !
这将是微不足道的,但是我们如何在不使用 !
的情况下做到这一点呢?
Check whether a number x
is nonzero using the legal operators except !
.
Examples: isNonZero(3) = 1
, isNonZero(0) = 0
Legal ops: ~
&
^
|
+
<<
>>
- Note : Only bitwise operators should be used.
if
,else
,for
, etc. cannot be used. - Edit1 : No. of operators should not exceed 10.
- Edit2 : Consider size of
int
to be 4 bytes.
int isNonZero(int x) {
return ???;
}
Using !
this would be trivial , but how do we do it without using !
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
以下函数示例应该适合您。
The following function example should work for you.
如果该函数非零,则返回
x
,否则返回0
。This function will return
x
if it is non-zero, otherwise it will return0
.int isNonZero(int x)
{
}
假设 Int 是 4 个字节。
如果值非零,则返回 1;
如果值为零,则返回 0。
int isNonZero(int x)
{
}
Let assume Int is 4 byte.
It will return 1 if value is non zero
if value is zero then it will return 0.
return ((val & 0xFFFFFFFF) == 0 ? 0:1);
return ((val & 0xFFFFFFFF) == 0 ? 0:1);
adamk 函数的对数版本:
也是最快的版本,但在汇编中:
可以用 C 编写类似于汇编版本的东西,您只需处理符号位并有一些差异。
编辑:这是我能想到的最快的 C 版本:
1)对于负数:如果设置了符号位,则该数字不是 0。2
)对于正数:
0 - n
将是否定,可以按照情况 1 进行检查。我在合法操作列表中没有看到-
,因此我们将使用~n + 1
代替。我们得到什么:
The logarithmic version of the adamk function:
And the fastest one, but in assembly:
Something similar to assembly version can be written in C, you just have to play with the sign bit and with some differences.
EDIT: here is the fastest version I can think of in C:
1) for negative numbers: if the sign bit is set, the number is not 0.
2) for positive:
0 - n
will be negaive, and can be checked as in case 1. I don't see the-
in the list of the legal operations, so we'll use~n + 1
instead.What we get:
假设 int 是 32 位(/* 编辑:这部分不再适用,因为我将参数类型更改为无符号 */ 并且有符号移位的行为与无符号移位完全相同)。
Assuming int is 32 bits (/* EDIT: this part no longer applies as I changed the parameter type to unsigned */ and that signed shifts behave exactly like unsigned ones).
为什么要把事情搞复杂呢?
它之所以有效,是因为 C 约定是每个非零值都表示 true,因为 isNonZero 返回合法的 int。
有些人认为,isNonZero() 函数应该为输入 3 返回 1,如示例所示。
如果您使用 C++,它仍然像以前一样简单:
现在,如果您提供 3,函数将返回 1。
好吧,它不适用于缺少正确布尔类型的 C。
现在,如果您假设整数是 32 位并且允许 +:
在某些体系结构上,您甚至可以避免最终的&1,只需将 x 强制转换为无符号(其运行时成本为空),但是这是未定义的行为,因此依赖于实现(取决于目标体系结构是否使用符号右移或逻辑右移)。
Why make things complicated ?
It works because the C convention is that every non zero value means true, as isNonZero return an int that's legal.
Some people argued, the isNonZero() function should return 1 for input 3 as showed in the example.
If you are using C++ it's still as easy as before:
Now the function return 1 if you provide 3.
OK, it does not work with C that miss a proper boolean type.
Now, if you suppose ints are 32 bits and + is allowed:
On some architectures you may even avoid the final
&1
, just by casting x to unsigned (which has a null runtime cost), but that is Undefined Behavior, hence implementation dependant (depends if the target architecture uses signed or logical shift right).~0
在补码机上生成减一。这是一个假设。)x
为零,则最高有效位仅因减一而翻转。我数了一下,有六个操作员。我可以使用
0xFFFFFFFF
来表示五个。转换为unsigned
不依赖于二进制补码机器 ;v) 。http://ideone.com/Omobw
~0
generates minus one on a two's complement machine. This is an assumption.)x
is zero.I count six operators. I could use
0xFFFFFFFF
for five. The cast tounsigned
doesn't count on a two's complement machine ;v) .http://ideone.com/Omobw
按位或数字中的所有位:
Bitwise OR all bits in the number:
基本上你需要或位。例如,如果您知道您的号码是 8 位宽:
basically you need to or the bits. For instance, if you know your number is 8 bits wide:
我的解决方案如下,
My solution is the following,
我的 C 解决方案。没有比较运算符。不适用于 0x80000000。
My solution in C. No comparison operator. Doesn't work with 0x80000000.
我的解决方案,虽然与你的问题不太相关
My solution,though not quite related to your question