![](/img/trans.png)
[英]Check if a number x is positive (x>0) by ONLY using bitwise operators in C
[英]Check if a number is non zero using bitwise operators in C
使用合法運算符檢查數字x
是否非零!
。
示例: isNonZero(3) = 1
, isNonZero(0) = 0
法律操作: ~
&
^
|
+
<<
>>
if
, else
, for
等不能使用。 int
大小視為4個字節。 int isNonZero(int x) {
return ???;
}
用!
這將是微不足道的,但我們如何在不使用的情況下做到這一點!
?
adamk函數的對數版本:
int isNotZero(unsigned int n){
n |= n >> 16;
n |= n >> 8;
n |= n >> 4;
n |= n >> 2;
n |= n >> 1;
return n & 1;
};
最快的一個,但是在組裝中:
xor eax, eax
sub eax, n // carry would be set if the number was not 0
xor eax, eax
adc eax, 0 // eax was 0, and if we had carry, it will became 1
類似於匯編版本的東西可以用C編寫,你只需要使用符號位和一些差異。
編輯:這是我在C中能想到的最快的版本:
1)對於負數:如果設置了符號位,則該數字不為0。
2)對於正面: 0 - n
將是否定的,並且可以按照情況1進行檢查。我沒有在合法操作列表中看到-
所以我們將使用~n + 1
代替。
我們得到了什么:
int isNotZero(unsigned int n){ // unsigned is safer for bit operations
return ((n | (~n + 1)) >> 31) & 1;
}
int isNonZero(unsigned x) {
return ~( ~x & ( x + ~0 ) ) >> 31;
}
假設int是32位(/ * EDIT:這部分不再適用,因為我將參數類型更改為無符號* /並且有符號的移位與無符號移位的行為完全相同)。
為什么讓事情復雜化?
int isNonZero(int x) {
return x;
}
它的工作原理是因為C約定是每個非零值都表示正確,因為isNonZero返回一個合法的int。
有人認為,isNonZero()函數應該為輸入3返回1,如示例中所示。
如果您使用的是C ++,它仍然像以前一樣簡單:
int isNonZero(int x) {
return (bool)x;
}
現在函數返回1,如果你提供3。
好吧,它不適用於C錯過適當的布爾類型。
現在,如果你認為int是32位且允許+:
int isNonZero(int x) {
return ((x|(x+0x7FFFFFFF))>>31)&1;
}
在某些體系結構上,您甚至可以通過將x轉換為無符號(具有空運行時成本)來避免最終&1
,但這是未定義行為,因此依賴於實現(取決於目標體系結構是使用帶符號還是邏輯右移)。
int isNonZero(int x) {
return ((unsigned)(x|(x+0x7FFFFFFF)))>>31;
}
int is_32bit_zero( int x ) {
return 1 ^ (unsigned) ( x + ~0 & ~x ) >> 31;
}
~0
產生二的補碼的機器上減一,這是一個假設。) x
為零,則最有效位僅作為減1的結果翻轉。 我算六個運營商。 我可以使用0xFFFFFFFF
五。 對unsigned
不依賴於二進制補碼機; v)。
按位OR或數字中的所有位:
int isByteNonZero(int x) {
return ((x >> 7) & 1) |
((x >> 6) & 1) |
((x >> 5) & 1) |
((x >> 4) & 1) |
((x >> 3) & 1) |
((x >> 2) & 1) |
((x >> 1) & 1) |
((x >> 0) & 1);
}
int isNonZero(int x) {
return isByteNonZero( x >> 24 & 0xff ) |
isByteNonZero( x >> 16 & 0xff ) |
isByteNonZero( x >> 8 & 0xff ) |
isByteNonZero( x & 0xff );
}
基本上你需要或位。 例如,如果您知道您的數字是8位寬:
int isNonZero(uint8_t x)
{
int res = 0;
res |= (x >> 0) & 1;
res |= (x >> 1) & 1;
res |= (x >> 2) & 1;
res |= (x >> 3) & 1;
res |= (x >> 4) & 1;
res |= (x >> 5) & 1;
res |= (x >> 6) & 1;
res |= (x >> 7) & 1;
return res;
}
我的解決方案如下,
int isNonZero(int n)
{
return ~(n == 0) + 2;
}
我的解決方案是C.沒有比較運算符。 不適用於0x80000000。
#include <stdio.h>
int is_non_zero(int n) {
n &= 0x7FFFFFFF;
n *= 1;
return n;
}
int main(void) {
printf("%d\n", is_non_zero(0));
printf("%d\n", is_non_zero(1));
printf("%d\n", is_non_zero(-1));
return 0;
}
以下函數示例應該適合您。
bool isNonZero(int x)
{
return (x | 0);
}
我的解決方案雖然與您的問題不太相關
int isSign(int x)
{
//return 1 if positive,0 if zero,-1 if negative
return (x > 0) - ((x & 0x80000000)==0x80000000)
}
如果非零,此函數將返回x
,否則返回0
。
int isNonZero(int x)
{
return (x);
}
if(x)
printf("non zero")
else
printf("zero")
return((val&0xFFFFFFFF)== 0?0:1);
int isNonZero(int x)
{
if ( x & 0xffffffff)
return 1;
else
return 0;
}
假設Int是4個字節。
如果值不為零,它將返回1
如果value為零,那么它將返回0。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.