Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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
C++ 用于检查数字是否在特定范围内的位旋转_C++_C_Algorithm_Bit Manipulation - Fatal编程技术网

C++ 用于检查数字是否在特定范围内的位旋转

C++ 用于检查数字是否在特定范围内的位旋转,c++,c,algorithm,bit-manipulation,C++,C,Algorithm,Bit Manipulation,我在ICU库(unicode的国际组件)的“source\common\unicode\utf.h”文件中发现了一些有趣的东西。位旋转用于检查数字是否在特定范围内 // Is a code point in a range of U+d800..U+dbff? #define U_IS_LEAD(c) (((c)&0xfffffc00)==0xd800) 我已经计算出神奇的数字(0xfffffc00)来自: MagicNumber = 0xffffffff - (HighBound -

我在ICU库(unicode的国际组件)的
“source\common\unicode\utf.h”
文件中发现了一些有趣的东西。位旋转用于检查数字是否在特定范围内

// Is a code point in a range of U+d800..U+dbff?
#define U_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
我已经计算出神奇的数字(0xfffffc00)来自:

MagicNumber = 0xffffffff - (HighBound - LowBound)
然而,我也发现这个公式并不适用于任何任意范围。这里有人知道这个公式在什么情况下有效吗


是否还有其他一些技巧来检查一个数字是否在特定范围内?

要应用这些技巧,这些数字的二进制表示形式必须具有一些共同的特征

0xD800 == 0b1101_1000_0000_0000
0xDBFF == 0b1101_1011_1111_1111
这个测试真正做的是屏蔽低10位。这通常写为

onlyHighBits = x & ~0x03FF
在该操作(“和非”)之后,
onlyHighBits
的低十位保证为零。这意味着,如果这个数字等于现在区间的下限,那么它以前就在区间的某个地方


此技巧适用于所有情况,即区间的下限和上限以相同的二进制数字开始,并且在某些情况下下限只有零,而上限只有一。在您的示例中,这是从右侧开始的第十个位置。

只要您要查找的范围以2的幂的倍数开始(即,数字二进制形式的低端的1个或多个位以0结尾),并且范围的大小为2^n-1(即,低&高==低和低|高==高),该公式就会起作用.

如果没有2^x边界,则类型可能会使用以下技巧:

如果
x>=0
x
可以通过以下方式进行检查:

  if Longword( x ) < Longword( N ) then ...
如果Longword(x)
这是因为有符号数中的负数对应于无符号数据类型中的最大数

您可以将此功能(当范围检查被禁用时)扩展到:

如果长单词(x-A)
现在,假设(B-A)是预先计算的,那么在SUB和CMP中有两个测试(范围
[A,B>

我只在真正需要的时候才使用这种优化;例如,它们会降低代码的可读性,每次测试只会减少几个时钟周期


类似C语言的读者注意:Longword是Delphi的无符号32位数据类型。

您能为“通常编写为”提供参考吗?我个人认为
a&~b
而不是
a&~b
不如
a&b==c
更直观,因为即使只是我个人的喜好,操作也更少。请注意
a&b==c
并不是你可能认为的意思(它的意思是
a&(b==c))
a&~b
a&~b
在词汇上是相同的,我同意后者是它的更好的转录,如果只是因为它通常是这样做的。你测试过它吗?假设数字是
9
,范围是
8..8+(2^14-1)
,该公式不适用于这种情况。嗯……N不需要大于基数末尾的0(因此对于8,N可以在1-3范围内)。我认为这太明显了,不值得一提。谢谢@Ritsaert,+1。对于任意范围,您需要另一种方法:
  if Longword( x - A ) < Longword ( ( B - A ) ) then ...