C按位,以十六进制逼近零。 0x15000000 - > 0x15 ???怎么样?

时间:2009-09-23 04:19:22

标签: c++

这甚至可能吗?

我如何截断零?

在整数中使用任何掩蔽技术(不允许:0x15000000& 0xff000000)。而且没有任何演员。

7 个答案:

答案 0 :(得分:5)

嗯,真的,如果你想截断右侧,天真的解决方案是:

uint input = 0x150000;
if(input)
{
    while(!(input & 0x01))  // Replace with while(!(input % 0x10)) if you are actually against masking.
    {
        input >>= 1;
    }
}

// input, here, will be 0x15.

但是,您可以展开此循环。如:

if(!(input & 0xFFFF)) { input >>= 16; }
if(!(input & 0x00FF)) { input >>= 8;  }
if(!(input & 0x000F)) { input >>= 4;  }  // Comment this line, down, if you want to align on bytes.
if(!(input & 0x0003)) { input >>= 2;  }  // Likewise here, down, to align on nybbles.
if(!(input & 0x0001)) { input >>= 1;  }

答案 1 :(得分:3)

没有任何屏蔽的一种方法(假设您要截断零):

int input = 0x150000;
while (input && !(input%2))
    input >>= 1;

这是一个完整的程序,用于说明它。

#include <stdio.h>

int main (int argc, char *argv[]) {
    int input = 0;
    if (argc < 2) {
        fprintf (stderr, "Needs at least one parameter.\n");
        return 1;
    }
    input = atoi (argv[1]);
    printf ("%x -> ", input);
    while (input && !(input%2))
        input >>= 1;
    printf ("%x\n",input);
    return 0;
}

如果要截断零 nybbles ,请使用:

while (input && ((input%16)==0))
    input >>= 4;

答案 2 :(得分:2)

John Gietzen的答案是我的最爱,但为了好玩,它实际上可以在没有循环的情况下完成!

如果您知道有多少尾随零,那么您可以向右移动该位数。有许多技术可用于查找位数。请参阅此处线性算法后面的几个部分:http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear

答案 3 :(得分:1)

除以16(一个nybble或十六进制数值),只要它是16的倍数:

if ( number )
    while ( number % 16 == 0 )
        number /= 16;

当然,如果你知道你永远不会将其作为输入,你可以将初始测试放弃为零。

答案 4 :(得分:1)

这是否算作掩蔽?

unsigned int truncate(unsigned int input)
{
    while (input != 0 && input % 0x10 == 0)
    {
        input /= 0x10;
    }

    return input;
}

答案 5 :(得分:0)

最简单的方法是将int转换为一个字节,所以现在你只需要8位,所以不是所有东西都被截断,但是它会有更少的零。

我希望这不是作业,但因为我担心它,给你所有的代码都不公平。

答案 6 :(得分:0)

向右移动24.确保您的变量未签名。