标签: bit-shift

为什么在C enum定义中使用Bitwise-Shift运算符?

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

c enums bit-shift bitwise-operators

38
推荐指数
3
解决办法
2万
查看次数

什么是(x&1)和(x >> = 1)?

我正在尝试分配:"在不使用sizeof()函数的情况下查找无符号整数数据类型中的位数."

我的设计是将整数转换为位然后计算它们.对于前:10 is 10105 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

38
推荐指数
4
解决办法
7万
查看次数

n是负数,正数还是零?返回1,2或4

我正在构建一个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. 在PPC上,您不必像在x86上那样更新CR0(其中ADD总是更改EFLAGS,即使不需要),您有两种ADD,一种更新.如果编译器选择使用更新版本,则意味着它将在某个时刻使用CR0,因此没有必要延迟...
  2. 有一个特别痛苦的指令叫做mtcrf,它可以让你随意改变CR0.你甚至可以把它设置为7,没有算术意义......这只会破坏保留"lastResult"变量的可能性.

c++ bit-manipulation bit-shift bit

35
推荐指数
3
解决办法
1967
查看次数

unsigned right Shift'>>>'Java中的运算符

可能重复:
为什么(-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吗?

java bit-shift

34
推荐指数
1
解决办法
5万
查看次数

c得到整数的第n个字节

我知道你可以通过使用获得第一个字节

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.

c byte bit-shift shift

33
推荐指数
2
解决办法
6万
查看次数

在C中声明64位变量

我有个问题.

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)

c bit-shift

32
推荐指数
2
解决办法
2561
查看次数

为什么1 << 31改为在C++ 14中实现定义?

在2014年之前的所有C和C++版本中,写作

1 << (CHAR_BIT * sizeof(int) - 1)
Run Code Online (Sandbox Code Playgroud)

导致未定义的行为,因为左移定义为等效于连续乘法2,并且此移位导致有符号整数溢出:

结果E1 << E2E1左移位E2位置; 腾出的位用零填充.[...]如果E1有一个带符号的类型和非负值,并且结果类型中可以表示E1×2 E2,那么这就是结果值; 否则,行为未定义.

但是在C++ 14中,文本已经改变<<但不是为了乘法:

E1 << E2E1左移位E2位置; 空位是零填充的.[...]否则,如果E1有一个有符号类型和非负值,并且E1×2 E2可以在结果类型的相应无符号类型中表示,那么转换为结果类型的那个值就是结果值; 否则,行为未定义.

现在的行为与签名类型的超出范围分配相同,即[conv.integral]/3所涵盖的行为:

如果目标类型已签名,则如果可以在目标类型(和位字段宽度)中表示该值,则该值不会更改; 否则,该值是实现定义的.

这意味着它仍然是不可移植的1 << 31(在具有32位int的系统上).那么为什么在C++ 14中做出这种改变呢?

c++ bit-shift c++14

32
推荐指数
1
解决办法
2597
查看次数

位移O(1)还是O(n)?

轮班操作O(1)还是O(n)

计算机通常需要更多操作来转移31个位置而不是移动1个位置是否有意义?

或者有意义的是,无论我们需要移动多少个位置,移位所需的操作数量都是恒定的?

PS:想知道硬件是否是合适的标签..

language-agnostic hardware cpu big-o bit-shift

30
推荐指数
4
解决办法
1万
查看次数

算术右移给出虚假的结果?

我必须在这里绝对疯狂,但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++ gcc bit-shift undefined-behavior

30
推荐指数
2
解决办法
1641
查看次数

何时在C#中使用Shift运算符<< >>?

我正在研究C#中的移位运算符,试图找出何时在我的代码中使用它们.

我找到了答案,但对于Java,你可以:

a)进行更快的整数乘法和除法运算:

*4839534*4*可以这样做: 4839534 << 2

要么

543894/2可以这样做:543894 >> 1

对于大多数处理器,移位操作比乘法更快.

b)将字节流重组为int值

c)用于加速图形操作,因为红色,绿色和蓝色由单独的字节编码.

d)将小数字装入一个长的...


对于b,c和d,我无法想象这里是一个真实的样本.

有谁知道我们是否可以在C#中完成所有这些项目?C#中的移位运算符是否有更实用的用途?

c# operators bit-shift

29
推荐指数
4
解决办法
2万
查看次数