2015-06-27 27 views
-1

size_t類型是一個無符號類型。因此,對size_t類型的值進行右移將邏輯上移位。考慮到size_t的寬度取決於實現,是否有任何方法在算術上右移size_t的值?算術右移一個size_t值

如果我的目標是從包含10size_t值創建一個位掩碼,還有另一種方法可以做到嗎?對於已知寬度的整數,我知道製作位掩碼的最簡單方法是左移整數的寬度 - 1,然後算術右移一路。

這工作我的64位系統上:

const size_t width = (sizeof(size_t) << 3)) - 1; 
size_t value = {boolean value}; 
value = ((int64_t) (value << width)) >> width; 

但是,當然,這是專門針對我的系統和喜歡它的系統。我可以用什麼來代替?

+0

如果我理解正確,你想要的是有效'size_t mask = original? -1:0;',如果通過「從包含1或0的值創建掩碼」,則表示從1位到'size_t'具有的多個位的符號擴展。 –

+0

是的,差不多。我的一部分想在沒有三元操作員的情況下完成。但我仍然很好奇,如果有一個好的方法來進行算術右移。 – skeggse

+1

爲什麼downvote,任何人? – skeggse

回答

2

您的原始代碼&hellip;

const size_t width = (sizeof(size_t) << 3)) - 1; 
size_t inpvalue = {zero or one}; 
size_t outvalue = ((int64_t) (value << width)) >> width; 

&hellip;可以以這種方式被簡化:

size_t inpvalue = {zero or one}; 
size_t outvalue = -inpvalue; 
+0

哦,是的,否定做到了。謝謝! – skeggse

1

嘗試這樣:

#define UNSIGNED_SRA(x,n) ((x)<=(0?(x):-1)/2 ? (x)>>(n) : ~(~(x)>>(n))) 

表達(0?(x):-1)/2評估爲用於具有高比特明確的類型的x最大值;如果您知道特定類型,例如size_t,則可以使用SIZE_MAX/2

具有算術右移操作碼的機器的任何優化編譯器都應該認識到,兩個分支對於它們處理的情況是相同的,並且完全優化分支,從而產生單個無分支操作。

1

有什麼辦法來算術右移一個爲size_t值?

是的,有。事實上,給定的無符號類型的一個值v,相信可以如下(例如用於size_t)執行算術右移位:

v = (v >> 1U) | (v & ~(~(size_t) 0 >> 1U)); 

基本上,它執行邏輯右移,然後設置最顯著位爲1,如果移位前最顯著位是1

這裏有一個小玩具程序運行幾個測試:

#include <stdio.h> 

void print_binary(size_t v) { 
    size_t mask = ~(~(size_t) 0 >> 1U); 
    while (mask) { 
     putchar('0'+!!(v&mask)); 
     mask >>= 1U; 
    } 
    putchar('\n'); 
} 

int main() { 
    size_t v; 

    // Some random number 
    v = 5583705; 
    print_binary(v); 
    v = (v >> 1U) | (v & ~(~(size_t) 0 >> 1U)); 
    print_binary(v); 

    v = ~(~(size_t) 0 >> 1U); 
    print_binary(v); 
    int i; 
    for (i = 0; i < 10; i++) { 
     v = (v >> 1U) | (v & ~(~(size_t) 0 >> 1U)); 
     print_binary(v); 
    } 

    return 0; 
} 

在我的機器,這個打印:

0000000000000000000000000000000000000000010101010011001101011001 
0000000000000000000000000000000000000000001010101001100110101100 
1000000000000000000000000000000000000000000000000000000000000000 
1100000000000000000000000000000000000000000000000000000000000000 
1110000000000000000000000000000000000000000000000000000000000000 
1111000000000000000000000000000000000000000000000000000000000000 
1111100000000000000000000000000000000000000000000000000000000000 
1111110000000000000000000000000000000000000000000000000000000000 
1111111000000000000000000000000000000000000000000000000000000000 
1111111100000000000000000000000000000000000000000000000000000000 
1111111110000000000000000000000000000000000000000000000000000000 
1111111111000000000000000000000000000000000000000000000000000000 
1111111111100000000000000000000000000000000000000000000000000000 

似乎工作正常。

對於你的具體問題,我相信dlask的答案是最好的方法,但我決定發佈這個答案,因爲你表現出興趣知道如何(以及如果)在無符號類型上進行算術右移。

+0

謝謝!我對一般情況很好奇(這種方式似乎是一個更好的問題)。 – skeggse