这个位操作代码背后的想法实现了5/8的数字?

时间:2017-01-30 02:31:19

标签: bit-manipulation

我正在研究一个问题,我必须使用位操作来计算给定数字的五分之八(5/8)吗?

对于正数,我可以很容易地做到。基本上,它是( (x << 2) + x )>> 3

然而,对于负数,它似乎不起作用。我环顾网络,显然,我必须增加一个因子7,但是,我不能安静地看看为什么需要这个?

3 个答案:

答案 0 :(得分:2)

使用轮向负无穷大进行分割,而正常C分组向零舍入。

也就是说,-9 / 8 == 1(即-1.25向零舍入为-1),但是-9 >> 2 == -2(即,`-1.25'向负无穷大舍入为 - 2)。

要解决这个问题,对于除以8 的特定情况,您可以在负数的情况下添加7以“调整”被除数,以便按预期进行舍入。

这个问题的全部内容假设您的C编译器为签名的右移实现了“算术右移”。几乎所有的架构/编译器组合都有,但标准并不保证。

答案 1 :(得分:1)

对于正面xx >> 3x / 8都朝向零。

对于否定xx >> 3向负无穷大舍入,而x / 8向零舍入。例子:

 -1 >> 3 = -1     -1 / 8 =  0     different
 -2 >> 3 = -1     -2 / 8 =  0     different
 -3 >> 3 = -1     -3 / 8 =  0     different
 -4 >> 3 = -1     -4 / 8 =  0     different
 -5 >> 3 = -1     -5 / 8 =  0     different
 -6 >> 3 = -1     -6 / 8 =  0     different
 -7 >> 3 = -1     -7 / 8 =  0     different
 -8 >> 3 = -1     -8 / 8 = -1     same
 -9 >> 3 = -2     -9 / 8 = -1     different
-10 >> 3 = -2    -10 / 8 = -1     different
-11 >> 3 = -2    -11 / 8 = -1     different
-12 >> 3 = -2    -12 / 8 = -1     different
-13 >> 3 = -2    -13 / 8 = -1     different
-14 >> 3 = -2    -14 / 8 = -1     different
-15 >> 3 = -2    -15 / 8 = -1     different
-16 >> 3 = -2    -16 / 8 = -2     same
-17 >> 3 = -3    -17 / 8 = -2     different
-18 >> 3 = -3    -18 / 8 = -2     different
-19 >> 3 = -3    -19 / 8 = -2     different

当分子(x)是分母(8)的倍数时,结果是相同的。对于其他7/8的结果,结果相差1.这意味着如果我们希望>> 3的行为与/ 8相同,我们需要更改分子。

一般来说,如果你有一个向下舍入的整数除法运算符,你可以通过在分子中加上(分母-1)来使它向上舍入。但是,让我们按照婴儿步骤到达那里。假设我们通过添加1来改变分子:

( -1 + 1) >> 3 =  0     -1 / 8 =  0     same
( -2 + 1) >> 3 = -1     -2 / 8 =  0     different
( -3 + 1) >> 3 = -1     -3 / 8 =  0     different
( -4 + 1) >> 3 = -1     -4 / 8 =  0     different
( -5 + 1) >> 3 = -1     -5 / 8 =  0     different
( -6 + 1) >> 3 = -1     -6 / 8 =  0     different
( -7 + 1) >> 3 = -1     -7 / 8 =  0     different
( -8 + 1) >> 3 = -1     -8 / 8 = -1     same
( -9 + 1) >> 3 = -1     -9 / 8 = -1     same
(-10 + 1) >> 3 = -2    -10 / 8 = -1     different
(-11 + 1) >> 3 = -2    -11 / 8 = -1     different
(-12 + 1) >> 3 = -2    -12 / 8 = -1     different
(-13 + 1) >> 3 = -2    -13 / 8 = -1     different
(-14 + 1) >> 3 = -2    -14 / 8 = -1     different
(-15 + 1) >> 3 = -2    -15 / 8 = -1     different
(-16 + 1) >> 3 = -2    -16 / 8 = -2     same
(-17 + 1) >> 3 = -2    -17 / 8 = -2     same
(-18 + 1) >> 3 = -3    -18 / 8 = -2     different
(-19 + 1) >> 3 = -3    -19 / 8 = -2     different

现在我们有2/8的结果匹配。尝试添加2:

( -1 + 2) >> 3 =  0     -1 / 8 =  0     same
( -2 + 2) >> 3 =  0     -2 / 8 =  0     same
( -3 + 2) >> 3 = -1     -3 / 8 =  0     different
( -4 + 2) >> 3 = -1     -4 / 8 =  0     different
( -5 + 2) >> 3 = -1     -5 / 8 =  0     different
( -6 + 2) >> 3 = -1     -6 / 8 =  0     different
( -7 + 2) >> 3 = -1     -7 / 8 =  0     different
( -8 + 2) >> 3 = -1     -8 / 8 = -1     same
( -9 + 2) >> 3 = -1     -9 / 8 = -1     same
(-10 + 2) >> 3 = -1    -10 / 8 = -1     same
(-11 + 2) >> 3 = -2    -11 / 8 = -1     different
(-12 + 2) >> 3 = -2    -12 / 8 = -1     different
(-13 + 2) >> 3 = -2    -13 / 8 = -1     different
(-14 + 2) >> 3 = -2    -14 / 8 = -1     different
(-15 + 2) >> 3 = -2    -15 / 8 = -1     different
(-16 + 2) >> 3 = -2    -16 / 8 = -2     same
(-17 + 2) >> 3 = -2    -17 / 8 = -2     same
(-18 + 2) >> 3 = -2    -18 / 8 = -2     same
(-19 + 2) >> 3 = -3    -19 / 8 = -2     different

显然,如果我们计算(x + i) >> 3,结果的(i + 1)/ 8匹配。因此,为了使所有结果匹配,我们为i求解(i + 1)/ 8 = 1,得到i = 7.如果我们将7加到分子上,这就是我们得到的结果:

( -1 + 7) >> 3 =  0     -1 / 8 =  0     same
( -2 + 7) >> 3 =  0     -2 / 8 =  0     same
( -3 + 7) >> 3 =  0     -3 / 8 =  0     same
( -4 + 7) >> 3 =  0     -4 / 8 =  0     same
( -5 + 7) >> 3 =  0     -5 / 8 =  0     same
( -6 + 7) >> 3 =  0     -6 / 8 =  0     same
( -7 + 7) >> 3 =  0     -7 / 8 =  0     same
( -8 + 7) >> 3 = -1     -8 / 8 = -1     same
( -9 + 7) >> 3 = -1     -9 / 8 = -1     same
(-10 + 7) >> 3 = -1    -10 / 8 = -1     same
(-11 + 7) >> 3 = -1    -11 / 8 = -1     same
(-12 + 7) >> 3 = -1    -12 / 8 = -1     same
(-13 + 7) >> 3 = -1    -13 / 8 = -1     same
(-14 + 7) >> 3 = -1    -14 / 8 = -1     same
(-15 + 7) >> 3 = -1    -15 / 8 = -1     same
(-16 + 7) >> 3 = -2    -16 / 8 = -2     same
(-17 + 7) >> 3 = -2    -17 / 8 = -2     same
(-18 + 7) >> 3 = -2    -18 / 8 = -2     same
(-19 + 7) >> 3 = -2    -19 / 8 = -2     same

答案 2 :(得分:0)

为了让它更具视觉效果,

取数字,比方说,-42(这不是5的倍数,但无论如何)

‭11010110

将一个小数点放在右边3个位置(这除以8)

11010.110 = -5.25

如何向上舍入:向所有分数位添加1(意味着iff不是全部为零,加法将进入整数部分),所以0.111,然后斩:

11010.110
    0.111     = 7/8
--------- +
11011.101     = -4.375
chop:
11011.000     = -5

要转换为普通整数,请移至小数点恰好在最低有效位之前:

11011.000 >>s 3 =
11111011.          = still -5, but in normal integer format

在代码中你只是将小数点放在虚拟中(所以什么都不做,但是就好像它在那里一样)并且分数是隐含的(所以7/8写成7)。因为正确的移位无论如何都会抛出这些位,所以斩断是不必要的。剩下的就是加7,然后换班。