簡體   English   中英

使用C中的按位運算符檢查數字是否為非零

[英]Check if a number is non zero using bitwise operators in C

使用合法運算符檢查數字x是否非零!

示例: isNonZero(3) = 1isNonZero(0) = 0

法律操作: ~ & ^ | + << >>

  • 注意:只應使用按位運算符。 ifelsefor等不能使用。
  • 編輯1:運營商數量不應超過10。
  • Edit2:將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;
}
  1. 減去1( ~0產生二的補碼的機器上減一,這是一個假設。)
  2. 只選擇翻轉為1的翻轉位。
  3. 如果x為零,則最有效位僅作為減1的結果翻轉。
  4. 將最高有效位移至最低有效位。

我算六個運營商。 我可以使用0xFFFFFFFF五。 unsigned不依賴於二進制補碼機; v)。

http://ideone.com/Omobw

按位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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM