簡體   English   中英

按位運算和轉移問題

[英]Bitwise operations and shifts problems

我正在測試函數fitsBits(int x,int n),我發現有一個條件不適合這個函數,有什么問題?

/*
* fitsBits - return 1 if x can be represented as an 
*  n-bit, two's complement integer.
*   1 <= n <= 32
*   Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
*   Legal ops: ! ~ & ^ | + << >>
*   Max ops: 15
*   Rating: 2
*/
int fitsBits(int x, int n) {
   int r, c;
   c = 33 + ~n;
   r = !(((x << c)>>c)^x);
   return r;
}

似乎它給出了錯誤的答案

fitsBits(0x80000000, 0x20);

它給了我1,但實際上應該是0 ......我怎么能解決它? 謝謝!

對於簽名類型,未定義導致溢出的左移。 因此,編譯器可以將(x<<c)>>c簡化為x ,並且整個函數減少到return 1;

可能你想使用無符號類型。

代碼中未定義行為的第二個原因是c可能大於或等於int的寬度。 超過整數類型寬度的移位是未定義的行為。

fitsBits(0x80000000, 0x20);

這個函數返回1 ,因為函數的第一個參數是int ,它實際上是(實際上是這些天)32位有符號整數。 簽名32位整數可以表示的最大值是0x7FFFFFFF,小於您傳入的值。因此,您的值被截斷並變為-0x80000000 ,這是32位整數可以表示的值。 因此,您的函數返回1 (是的,我的第一個參數是可以使用0x20 = 32位表示的東西)。

如果您希望函數正確地將數字0x80000000分類為無法使用32位表示的內容,則需要更改函數的第一個參數的類型。 一個選項可能是使用unsigned int ,但是從您的問題定義中看起來您需要正確處理負數,因此您的剩余選項是long long int ,可以保存-0x80000000000000000x7FFFFFFFFFFFFFFF之間的數字。

你需要做更多的調整:你需要通過使用LL后綴明確指定你的常量類型為long long ,現在你需要移動64 - c ,而不是32 - c

#include <stdio.h>

int fitsBits(long long x, int n) {
   long long r;
   int c;
   c = 65 + ~n;
   r = !(((x << c)>>c)^x);
   return r;
}

int main() {
    printf("%d\n", fitsBits(0x80000000LL, 0x20));
    return 0;
}

鏈接到IDEONE: http ://ideone.com/G8I3kZ

r = (((x << c)>>c)^x); //This will give you 0, meaning r = 0;

要么

r = !((x << c)>>c);

您的功能可以簡化為

int fitsBits(int x) {

    int r, c; 
    c = 33; 
    r = (((x << c)>>c)^x);

    return r;
}

請注意,當NOT( ! )被帶來時,你要求r相反

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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