2015-06-27 23 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