几天前,我的老师告诉我,可以仅使用位运算符检查给定点是否在给定矩形内。这是真的吗?如果是这样,我该怎么做?
答案 0 :(得分:3)
这可能无法解答您的问题,但您正在寻找的可能是这个 These are the tricks由Sean Eron Anderson编写,他甚至为那些能找到一个bug的人提供了10美元的赏金。我在这里找到的最接近的是一个宏,它可以找到任何整数 X 是否有一个词是between M and N
确定单词是否在m和n之间有一个字节
当m < n,该技术测试单词x是否包含无符号字节值,使得m <1。价值&lt; ñ。当n和m为常数时,它使用7次算术/逻辑运算。 注意:等于n的字节可以通过可能在误报之间报告,因此如果需要某个结果,则应该按字符检查。
要求:x&gt; = 0; 0℃; = M&LT; = 127; 0℃; = N&LT; = 128
#define likelyhasbetween(x,m,n) \ ((((x)-~0UL/255*(n))&~(x)&((x)&~0UL/255*127)+~0UL/255*(127-(m)))&~0UL/255*128)
这种技术适用于快速预测试。一个变量需要再做一次操作(对于常数m和n总共8次),但提供的确切答案是:
#define hasbetween(x,m,n) \ ((~0UL/255*(127+(n))-((x)&~0UL/255*127)&~(x)&((x)&~0UL/255*127)+~0UL/255*(127-(m)))&~0UL/255*128)
答案 1 :(得分:2)
x,如果{x0<x<x1 and y0<y<y1}
{x0<x and x<x1 and y0<y and y<y1}
中
如果我们可以模拟&lt;有了位操作符,那我们就好了。
说些什么是什么意思?在二进制?考虑
a: 0 0 0 0 1 1 0 1
b: 0 0 0 0 1 0 1 1
在上面,a> b,因为它包含第一个1,其中b中的对应部分是0.我们是那些寻找最左边位的那些myBit!=otherBit
。 (==或equiv
是一个按位运算符,可以用和/或/不表示)
然而,我们需要一些方法来将信息以一位传播到多位。所以我们问自己:我们可以仅使用“位”运算符“编码”一个函数,这相当于if(q,k,a,b) = if q[k] then a else b
。答案是肯定的:
and
一起使用10000 ... 0 or
右移版本。这将位首先复制到第二位。我们重复这个过程,直到整个单词与第一位相同(例如64次)mask
,我们的函数为(mask and a) or (!mask and b)
:如果a
的{{1}}位为真,则结果为k
,其他为结果将是q
取位向量c = b
,我们使用a!=b and a==1111..1 and b==0000..0
函数连续测试第一位是1,然后第二位是1,等等:
if
这需要a<b :=
if(c,0,
if(a,0, B_LESSTHAN_A, A_LESSTHAN_B),
if(c,1,
if(a,1, B_LESSTHAN_A, A_LESSTHAN_B),
if(c,2,
if(a,2, B_LESSTHAN_A, A_LESSTHAN_B),
if(c,3,
if(a,3, B_LESSTHAN_A, A_LESSTHAN_B),
if(...
if(c,64,
if(a,64, B_LESSTHAN_A, A_LESSTHAN_B),
A_EQUAL_B)
)
...)
)
)
)
)
个步骤。但是,如果不允许递归,则可以使用递归定义的函数写入3行,或者使用定点组合符。
然后我们将其转换为更大的功能:wordsize
答案 2 :(得分:2)
如果数字是有限正整数,则可能。
假设我们有一个由(a1,b1)
和(a2,b2)
表示的矩形。给定一个点(x,y)
,我们只需要评估表达式(a1<x) & (x<a2) & (b1<y) & (y<b2)
。所以现在的问题是找到表达式c的相应位操作
设ci
为数字c
的第i位(可以通过屏蔽ci
和位移来获得)。我们证明,对于最多n
位的数字,c<d
相当于r_(n-1)
,其中
r_i = ((ci^di) & ((!ci)&di)) | (!(ci^di) & r_(i-1))
证明:当ci
和di
不同时,左边的表达式可能为真(取决于((!ci)&di)
),否则正确的表达式可能是是(取决于r_(i-1)
,这是下一位的比较)。
表达式((!ci)&di)
实际上等同于位比较ci < di
。因此,这个递归关系返回true,它从左到右逐位比较,直到我们可以确定c
小于d
。
因此,对应于比较运算符的纯位运算表达式,因此可以使用纯位运算在矩形内找到一个点。
编辑:实际上不需要条件语句,只需展开r_(n+1)
,然后完成。