如何使用位运算符清除位

How to clear bits using Bitwise Operators

本文关键字:清除 运算符 何使用      更新时间:2023-10-16

我有兴趣学习如何清除位,这样我就可以使用二进制值的一部分,而不是整个值。我希望用它来从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;
}