如何使用位运算符清除位
How to clear bits using Bitwise Operators
我有兴趣学习如何清除位,这样我就可以使用二进制值的一部分,而不是整个值。我希望用它来从IEEE单精度浮点形式中获得有符号位、指数和有效位
然而,我对十六进制并不完全熟悉,我想知道是否可以得到你的帮助。
到目前为止,我的想法如下:有符号位-按0x100000000对二进制值进行逐位AND运算,得到第一个仅限位的
Exponent-将值向左移动一次,然后按位和新值移动0xFF000000以获得指数的前八位
显著-向左移动数值23次
由于每一个都需要对原始值进行处理,所以我还计划将值存储到另一个寄存器中。这样,我仍然可以在不"伤害"原作的情况下对价值进行研究。然后,有符号位、指数和有符号位的值将存储在单独的寄存器中。
注意:我正在处理IEEE-754单精度浮点格式的答案:
签名:并用0x80000000
屏蔽您的号码。若结果为0,则数字为正,否则为负。Exponent:用0x7F800000
对数字进行AND掩码,然后向右移动23位。曼蒂萨:用0x007FFFFF
屏蔽你的号码。
要了解我为什么使用这些数字,只需将每个掩码转换为二进制形式,并将其放在浮点数的二进制表示下:
SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM = format of a floating point number: S=sign,
E=exponent,
M=mantisa
10000000000000000000000000000000 = 80000000h (isolate sign bit)
01111111100000000000000000000000 = 7F800000h (isolate exponent, 8 bits)
00000000011111111111111111111111 = 007FFFFFh (isolate mantissa, 23 bits)
要将二进制数转换为十六进制,只需将其排列在4位组中,并将每组转换为一个十六进制数字:
例如:
01111111100000000000000000000000 is arranged as:
0111 1111 1000 0000 0000 0000 0000 0000 which is translated into hex as this:
7 F 8 0 0 0 0 0
以下是一些NASM语法32位
MOV eax, DWORD [ssValue]
MOV ebx, DWORD [signMask] ;; 80000000h
MOV ecx, DWORD [expoMask] ;; 7F800000h
MOV edx, DWORD [sigfMask] ;; 007FFFFFh
AND ebx, eax
AND ecx, eax
AND edx, eax ;; edx is the significand
SHR ebx, 31 ;; ebx is the sign
SHR ecx, 23 ;; ecx is the exponent
在C中,它将类似于
int sign = value & 0x80000000;
int expo = value & 0x7F800000;
int sigf = value & 0x007FFFFF;
sign >>= 31;
expo >>= 23;
如果要更正具有127(7Fh)偏差的指数,请编辑
if(expo == 0x0) {
// denormal
} else if(expo == 0xFF) {
// +inf or nan depending on sigf
} else { // -126 to 127 range
expo -= 0x7F;
}
编辑2在Java等其他语言中,">>"是一个带符号的移位运算符。
sign >>= 31; // would result in 0 or -1 (0xFFFFFFFF) if the sign bit was 1
sign >>>= 31; // would result in 0 or 1
在java中,位异或运算可以用来清除位。您可以使用将特定字符串转换为整数
我写了这个函数来清除最左边的位,不管符号是什么。
public static void main(String[] args) {
System.out.println(String.format( "-2 binary=%32s",Integer.toBinaryString(-2)));
int dropped = toggleLeftMostBit(-2);
System.out.println(String.format( "-2 dropped left bit val= %dn binary=%32s",dropped,Integer.toBinaryString(dropped)));
}
private static int toggleLeftMostBit(int i)
{
return i ^ Integer.highestOneBit(i);
}
private static int toggleNthBit(int i, int n)
{
return i ^ 1<< n-1;
}
相关文章:
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 清除具有已删除赋值运算符的成员的类实例
- 如何使用删除 [] 运算符清除动态分配的内存?(无法使用常规删除语法清除)
- 如何使用位运算符清除位
- 为什么运算符 new 清除的内存多于请求的内存