家庭作业 - C位拼图 - 使用C位操作执行%(无循环,条件,函数调用等)

时间:2012-08-27 19:22:07

标签: c bit-manipulation

我完全坚持如何做这个家庭作业问题并寻找一两个提示让我继续前进。我只限于20次操作(=在这20次中不算数。)

我应该填写一个看起来像这样的函数:

    /* Supposed to do x%(2^n).
       For example: for x = 15 and n = 2, the result would be 3.

       Additionally, if positive overflow occurs, the result should be the
       maximum positive number, and if negative overflow occurs, the result
       should be the most negative number.
     */
    int remainder_power_of_2(int x, int n){

      int twoToN = 1 << n;

      /* Magic...? How can I do this without looping? We are assuming it is a
         32 bit machine, and we can't use constants bigger than 8 bits
         (0xFF is valid for example).
         However, I can make a 32 bit number by ORing together a bunch of stuff.
         Valid operations are: << >> + ~ ! | & ^
       */

      return theAnswer;
    }

我想也许我可以将twoToN移到左边......直到我以某种方式检查(没有if / else)它大于x,然后再向右移一次......然后xor与x ...并重复?但我只有20次行动!

3 个答案:

答案 0 :(得分:3)

提示:在十进制系统中,以10的幂为模进行模数,您只需保留最后几位数并将另一数字置零。例如。 12345%100 = 00045 = 45.嗯,计算机编号是二进制的。所以你必须使二进制数字(位)为空。因此,请查看各种位操作运算符(&|^)。

答案 1 :(得分:2)

由于二进制是基数2,所以余数mod 2 ^ N完全由值的最右边位表示。例如,请考虑以下32位整数:

00000000001101001101000110010101

这有两个恭维值3461525.余数mod 2恰好是最后一位(1)。余数mod 4(2 ^ 2)恰好是最后2位(01)。余数mod 8(2 ^ 3)恰好是最后3位(101)。通常,余数mod 2 ^ N恰好是最后N位。

简而言之,您需要能够获取输入数字,并以某种方式将其屏蔽以仅获取最后几位。

小贴士:说你正在使用mod 64.二进制文件中64的值是:

00000000000000000000000001000000

您感兴趣的模数是最后6位。我将为您提供一系列操作,可以将该数字转换为掩码(但我不会告诉您它们是什么,您可以自己解决它们:D)

00000000000000000000000001000000 // starting value
11111111111111111111111110111111 // ???
11111111111111111111111111000000 // ???
00000000000000000000000000111111 // the mask you need

这些步骤中的每一步都等同于可以对int类型执行的一个操作。你能搞清楚吗?你能看到如何简化我的步骤吗? :d

另一个提示:

00000000000000000000000001000000 //  64
11111111111111111111111111000000 // -64

答案 2 :(得分:0)

由于你的除数总是2的幂,所以很容易。

uint32_t remainder(uint32_t number, uint32_t power)
{
    power = 1 << power;
    return (number & (power - 1));
}

假设您输入数字5,除数为2

`00000000000000000000000000000101` number
AND
`00000000000000000000000000000001` divisor - 1
=
`00000000000000000000000000000001` remainder (what we expected)

假设您输入数字7,除数为4

`00000000000000000000000000000111` number
AND
`00000000000000000000000000000011` divisor - 1
=
`00000000000000000000000000000011` remainder (what we expected)

只有除数是2的幂(除数= 1除外)才有效,所以请小心使用。