Apple有时在其枚举定义中使用Bitwise-Shift运算符.例如,在CGDirectDisplay.h文件中,它是Core Graphics的一部分:
enum {
kCGDisplayBeginConfigurationFlag = (1 << 0),
kCGDisplayMovedFlag = (1 << 1),
kCGDisplaySetMainFlag = (1 << 2),
kCGDisplaySetModeFlag = (1 << 3),
kCGDisplayAddFlag = (1 << 4),
kCGDisplayRemoveFlag = (1 << 5),
kCGDisplayEnabledFlag = (1 << 8),
kCGDisplayDisabledFlag = (1 << 9),
kCGDisplayMirrorFlag = (1 << 10),
kCGDisplayUnMirrorFlag = (1 << 11),
kCGDisplayDesktopShapeChangedFlag = (1 << 12)
};
typedef uint32_t CGDisplayChangeSummaryFlags;
Run Code Online (Sandbox Code Playgroud)
为什么不简单地在"普通" 枚举中使用递增int?
我正在尝试分配:"在不使用sizeof()函数的情况下查找无符号整数数据类型中的位数."
我的设计是将整数转换为位然后计算它们.对于前:10 is 1010和5 is 101
将整数转换为位表示形式显示如下:
do
{
Vec.push_back( x & 1 )
}
while ( x >>= 1 );
Run Code Online (Sandbox Code Playgroud)
我不想只是复制粘贴的东西.当我使用F-10时,我看到(x & 1)正在做什么,但我不知道它是名字还是它如何完成它的工作(比较一些东西?).我也知道>=哪个"大于或等于"但是什么x >>= 1?
注意:标记的副本是JavaScript而不是C++
c++ bit-manipulation bit-shift bitwise-operators bitwise-and
我正在构建一个PowerPC解释器,它运行得很好.在Power架构中,条件寄存器CR0(x86上的EFLAGS)几乎在任何指令上都会更新.它是这样设置的.如果最后一个结果为负,则CR0的值为1,如果最后结果为正,则为2,否则为4.
我的第一个天真的解释方法是:
if (n < 0)
cr0 = 1
else if (n > 0)
cr0 = 2;
else
cr0 = 4;
Run Code Online (Sandbox Code Playgroud)
但是我知道所有这些分支都不是最佳的,每秒运行数百万次.我已经看到了一些有点黑客攻击,但似乎没有任何东西.例如,我发现许多例子将数字转换为-1,0或1,相应地符号为0.但是如何使-1 = 1,1 = 2 = 0?我要求Bit Hackers的帮助......
提前致谢
更新: 首先:谢谢你们,你们一直很棒.我会仔细测试你的所有代码以获得速度,你将成为第一个知道谁是胜利者的代码.
@jalf:关于你的第一个建议,我实际上并没有在每条指令上计算CR0.我宁愿保留一个lastResult变量,当(和如果)以下指令要求标志时,进行比较.三个主要动机让我回到"每次"更新:
可能重复:
为什么(-1 >>> 32)= -1?
无符号右移运算符在最左边插入0.所以,当我这样做
System.out.println(Integer.toBinaryString(-1>>>30))
Run Code Online (Sandbox Code Playgroud)
11
Run Code Online (Sandbox Code Playgroud)
因此,它在最左边的位中插入0.
System.out.println(Integer.toBinaryString(-1>>>32))
Run Code Online (Sandbox Code Playgroud)
11111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)
不应该是0吗?
我知道你可以通过使用获得第一个字节
int x = number & ((1<<8)-1);
Run Code Online (Sandbox Code Playgroud)
要么
int x = number & 0xFF;
Run Code Online (Sandbox Code Playgroud)
但我不知道如何获得整数的第n个字节.例如,1234是00000000 00000000 00000100 11010010作为32位整数如何获得所有这些字节?第一个是210,第二个是4,最后两个是0.
我有个问题.
uint64_t var = 1; // this is 000000...00001 right?
Run Code Online (Sandbox Code Playgroud)
在我的代码中,这有效:
var ^ (1 << 43)
Run Code Online (Sandbox Code Playgroud)
但它怎么知道1应该是64位?我不应该写这个吗?
var ^ ( (uint64_t) 1 << 43 )
Run Code Online (Sandbox Code Playgroud) 在2014年之前的所有C和C++版本中,写作
1 << (CHAR_BIT * sizeof(int) - 1)
Run Code Online (Sandbox Code Playgroud)
导致未定义的行为,因为左移定义为等效于连续乘法2,并且此移位导致有符号整数溢出:
结果
E1 << E2是E1左移位E2位置; 腾出的位用零填充.[...]如果E1有一个带符号的类型和非负值,并且结果类型中可以表示E1×2 E2,那么这就是结果值; 否则,行为未定义.
但是在C++ 14中,文本已经改变<<但不是为了乘法:
值
E1 << E2是E1左移位E2位置; 空位是零填充的.[...]否则,如果E1有一个有符号类型和非负值,并且E1×2 E2可以在结果类型的相应无符号类型中表示,那么转换为结果类型的那个值就是结果值; 否则,行为未定义.
现在的行为与签名类型的超出范围分配相同,即[conv.integral]/3所涵盖的行为:
如果目标类型已签名,则如果可以在目标类型(和位字段宽度)中表示该值,则该值不会更改; 否则,该值是实现定义的.
这意味着它仍然是不可移植的1 << 31(在具有32位int的系统上).那么为什么在C++ 14中做出这种改变呢?
轮班操作O(1)还是O(n)?
计算机通常需要更多操作来转移31个位置而不是移动1个位置是否有意义?
或者有意义的是,无论我们需要移动多少个位置,移位所需的操作数量都是恒定的?
PS:想知道硬件是否是合适的标签..
我必须在这里绝对疯狂,但gcc 4.7.3在我的机器上给出了最荒谬的结果.这是我正在测试的确切代码:
#include <iostream>
using namespace std;
int main(){
unsigned int b = 100000;
cout << (b>>b) << endl;
b = b >> b;
cout << b << endl;
b >>= b;
cout << b << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,这是正确的本身转移任意数量应该导致0(n/(2^n) == 0与整数除法,n>1和正/无符号),但不知何故,这里是我的输出:
100000
100000
100000
Run Code Online (Sandbox Code Playgroud)
我疯了吗?可能会发生什么?
我正在研究C#中的移位运算符,试图找出何时在我的代码中使用它们.
我找到了答案,但对于Java,你可以:
a)进行更快的整数乘法和除法运算:
*4839534*4*可以这样做: 4839534 << 2
要么
543894/2可以这样做:543894 >> 1
对于大多数处理器,移位操作比乘法更快.
b)将字节流重组为int值
c)用于加速图形操作,因为红色,绿色和蓝色由单独的字节编码.
d)将小数字装入一个长的...
对于b,c和d,我无法想象这里是一个真实的样本.
有谁知道我们是否可以在C#中完成所有这些项目?C#中的移位运算符是否有更实用的用途?