相关疑难解决方法(0)

为什么在移位32位值时仅使用移位操作数的低5位?(例如(UInt32)1 << 33 == 2)

请考虑以下代码:

UInt32 val = 1;
UInt32 shift31 = val << 31;                    // shift31  == 0x80000000
UInt32 shift32 = val << 32;                    // shift32  == 0x00000001
UInt32 shift33 = val << 33;                    // shift33  == 0x00000002
UInt32 shift33a = (UInt32)((UInt64)val << 33); // shift33a == 0x00000000
Run Code Online (Sandbox Code Playgroud)

它不会生成警告(关于使用大于32的班次),因此它必须是预期的行为.

实际上被放到生成的程序集中的代码(或者至少是Reflector对代码的解释)是

 uint val = 1;
 uint shift31 = val << 0x1f;
 uint shift32 = val;
 uint shift33 = val << 1;
 uint shift33a = val << 0x21;  
Run Code Online (Sandbox Code Playgroud)

IL(再次,使用Reflector)是

L_0000: nop 
L_0001: ldc.i4.1 
L_0002: stloc.0 …
Run Code Online (Sandbox Code Playgroud)

c# bit-shift

14
推荐指数
1
解决办法
1995
查看次数

Java Integer左移的奇怪结果

我现在对java左移操作有点困惑,

1<<31 =  0x80000000  --> this I can understand
Run Code Online (Sandbox Code Playgroud)

1<<32 =  1       Why is this?
1<<33 =  2       
Run Code Online (Sandbox Code Playgroud)

看起来更多的移动值,采用模数32的值.

感谢大家的回复和JLS的报价.

我只想知道更多.知道它以这种方式设计的原因吗?或者只是一些惯例?显然C没有这个怪癖?

感谢@paxdiablo.看起来像C声明这个行为未定义.

我在这里有一些个人假设:

ARM体系结构参考手册A7.1.38

语法LSL Rd,Rm,#immed_5

哪里:

Rd 是存储操作结果的寄存器.

Rm是包含要移位的值的寄存器.

immed_5指定移位量,范围为0到31.

在指令级别,immedidate immed_5只需要5位就可以避免无意义的操作,从而节省一些指令空间.我想高级语言只是将这个约定统一起来,以避免在编译指令时产生无意义的努力.

java bit-manipulation bit-shift

7
推荐指数
1
解决办法
1015
查看次数

标签 统计

bit-shift ×2

bit-manipulation ×1

c# ×1

java ×1