C 如何从二进制数中删除尾随零

C 如何从二进制数中删除尾随零,c,binary,bit-manipulation,long-integer,C,Binary,Bit Manipulation,Long Integer,我有一个long-long类型的整数,在删除该整数的二进制表示形式中的尾随零后,我希望将其转换为新整数。以下是一种蛮力方法: long-long删除尾随零(long-long v){ 如果(v!=0){ 而((v&1)==0) v/=2; } 返回v; } 下面是一种直接处理无符号数字的方法,但除法的成本可能比上面的迭代要高: unsigned long long remove_training_零(unsigned long v){ 如果(v!=0){ //v和(v-1)仅在尾随的0位加1中

我有一个long-long类型的整数,在删除该整数的二进制表示形式中的尾随零后,我希望将其转换为新整数。

以下是一种蛮力方法:

long-long删除尾随零(long-long v){
如果(v!=0){
而((v&1)==0)
v/=2;
}
返回v;
}
下面是一种直接处理无符号数字的方法,但除法的成本可能比上面的迭代要高:

unsigned long long remove_training_零(unsigned long v){
如果(v!=0){
//v和(v-1)仅在尾随的0位加1中不同
//将v^(v-1)右移1,然后加1,得到2的幂
//除以v以删除所有尾随的0位
v/=(((v^(v-1))>>1)+1;
}
返回v;
}
哈罗德建议简化:

unsigned long long remove_trailing_zeroes(unsigned long long v) {
    if (v != 0) {
        // `-v`, which is `(~v + 1)` has all bits flipped except the least
        // significant 1 bit.
        // dividing v by `-v & v` shifts all trailing zero bits out,
        v /= -v & v;
    }
    return v;
}
可以将其简化为单个表达式:

unsigned long long remove_training_零(unsigned long v){
返回v?v/(-v&v):v;
}
为了避免除法,您可以使用一种有效的方法计算
v^(v-1)
中的位数,并将
v
右移一个小于该位数的位数。这也适用于
0
,因此您将获得无分支代码


你可以在这个引人入胜的词

中找到其他方法,你走了多远?@gmatht没有尝试,而是找到了另一种方法来完成我正在做的任务。不管怎样,如果你能想出一个解决办法,请告诉我。谢谢。如果值为
LLONG\u MIN
,您希望得到什么结果?1?@chux,我不确定。我只是想删除尾随的零,如果它们不存在,则返回原始整数。@pcgamer:问题是,您希望数字的高位对于删除的每个尾随的0位都设置为0,还是对于负数设置为
1
,从而保留符号。