簡體   English   中英

僅使用“〜&^ |實現邏輯右移 + << >> =“運營商和20個運營

[英]Implementing logical right shift using only “~ & ^ | + << >> =” operators and 20 operations

所以我有一個賦值,我必須在c中編寫一個函數,它只使用〜,&,^,|的按位運算 ,+,<<,>>和=。 我只需要使用20次操作。 並且我不允許使用控制結構,例如if-else,for,while,switch,或其他任何可以在條件塊中使用代碼的東西。 同樣類型轉換也是輸出 ,並且未在函數頭中聲明的字節(給我),限制為1個字節或8位值; 所以我有十六進制到FF。

我必須編寫的函數是邏輯右移。 因此,不是填充符號位的位,而是填充0

這就是我所做的:

int logicalShift(int x, int n) {
    int op=0xFFFFFFFF;
    int tcn=(~n+1);
    int sizeshift=0x20 & tcn;
    op=(op<<sizeshift);
    return ((x>>n) + (op));
}

這是我期望獲得的(對於x = 0x80000000,並且n = 0x01)我期望得到0x40000000,其為十進制的1073741824。 這就是我得到的。 然而(對於x = 0x80000000,n = 0x0我期望得到0x80000000,但是我得到0x7fffffff這是我的答案減去一點。我可以添加一點,但它弄亂了第一個答案。所以我做錯了什么我有一個案子而不是另一個案子。我也試過了。

int logicalShift(int x, int n) {
    int op=0xFFFFFFFF;
    int tcn=(~n+1);
    int sizeshift=0x20 & tcn;
    op=(op<<sizeshift);
    return ((x>>n) + (op  ^ ~n));
}

我認為,如果我對0位的所有1的符號位進行異或運算,那么當它通過編譯器轉換為2的補碼時,我會得到一些非負的(也就是)0x7fffffff。 它最終使情況變得更糟。 請讓我指出正確的方向我應該考慮什么?為什么?

邏輯移位和算術移位之間的差異是從左側移入的位。 要在算術方面實現邏輯移位,您可以執行算術移位,然后清除新位。 在偽代碼中:

  1. 生成一個掩碼 ,當與結果進行AND運算時,該掩碼將清除最左邊的n位。
  2. 向右移動n位。
  3. 和面具。

使用AND意味着您不必關心哪些位被移入。您只需要無條件地將它們設置為0。

那么問題是如何生成掩碼。 我會把它作為鍛煉給你。

如果未設置符號位,則(x >> n) == (x >>> n) 如果符號位置位,我們在執行移位之前將其屏蔽掉,然后將其添加回: (x & 0x7FFFFFFF) >> n | (0x40000000 >> (n - 1)) (x & 0x7FFFFFFF) >> n | (0x40000000 >> (n - 1))

如果我們知道,我們擁有的兩種情況中的哪一種,計算就變得更容易了。 如果我們可以使用if ,我們可以將這兩種情況結合起來。 我們必須模仿有條件的。

int signBit1 = (x & 0x7FFFFFFF) >> n | (0x40000000 >> (n - 1));
int signBit0 = x >> n;
var signBitIsolated = x & 0x80000000; // either 0 or 0x80000000
var signMask = signBitIsolated >> 31; //either 0 or 0xFFFFFFFF
var combined = (signBit0 & ~signMask) | (signBit1 & signMask);
return combined;

我們通過生成全零或全1掩碼以及兩種情況來模擬條件。

我想你說輸入域只限於一個字節。 同樣的想法適用,但具有不同的常數。

暫無
暫無

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

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