Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bit manipulation 这个想法背后的位操作代码实现了5/8的一个数?_Bit Manipulation - Fatal编程技术网

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

Bit manipulation 这个想法背后的位操作代码实现了5/8的一个数?,bit-manipulation,Bit Manipulation,我正在研究一个问题,我必须使用位运算计算给定数字的八分之五(5/8) 对于正数,我可以很容易地做到。基本上,它是((x>3) 然而,对于负数,它似乎不起作用。我环顾了一下网络,显然,我必须添加一个因子7,然而,我不明白为什么需要这样做?使用向负无穷大方向移动的除法,而普通的C除法则向零方向移动 也就是说,-9/8==1(即,-1.25向零舍入为-1),但-9>-2==2(即,“-1.25”向负无穷大舍入为-2) 为了解决这个问题,对于被8除的特定情况,在负数的情况下,您可以加7来“调整”股息,以

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

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

然而,对于负数,它似乎不起作用。我环顾了一下网络,显然,我必须添加一个因子7,然而,我不明白为什么需要这样做?

使用向负无穷大方向移动的除法,而普通的C除法则向零方向移动

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

为了解决这个问题,对于被8除的特定情况,在负数的情况下,您可以加7来“调整”股息,以使四舍五入如您所期望的那样进行



整个问题假设您的C编译器为有符号右移实现了“算术右移”。几乎所有的体系结构/编译器组合都实现了,但标准并不能保证这一点。

对于正
x
x>>3
x/8
都向零进位

对于负
x
x>>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
显然,如果我们计算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

为了让它更直观

以数字为例,-42(不是5的倍数,但无论如何)

将一个基点从右起3处(除以8)

如何四舍五入:将1与所有分数位相加(即如果分数位不全为零,则加法将进入整数部分),因此为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,然后移位。

逻辑很复杂,我不太明白,但是如果你只是对x求反呢?
-(-x>3)
,然后重新对结果求反?@dana该逻辑只是
x*5/8
,但除法是向下舍入,而不是向上舍入zero@harold你能详细说明为什么需要加7吗?我不能安静地想象它。你能指出为什么我们加7而不是其他东西吗?它在数学上有什么帮助?会有所不同t表示不同的分母?当你用移位法除以负数
N
时,你可以加
N-1
来向零取整。因此
8-1==7
。你可以自己做一些例子-尝试
-9,-8和-7
来测试“边界”情况。这类似于你如何“取整”在C中使用正规除法,在除数上加上除数-1,你的意思是负无穷大,对吗?一些负号似乎也有disappeared@harold-没错,我的意思是消极的不公平。我加了大约3到4个消极的符号,希望这就是所有的符号!无可否认,我有一个积极的div例子伊森起初意识到它应该是负面的,但转换得很差。
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