如何使用Bitwise运算符清除位

时间:2013-12-03 02:08:44

标签: c++ assembly bit-manipulation clear

我有兴趣学习如何清除位,以便我可以使用部分二进制值,而不是整个事物。我希望用它来获取IEEE单精度浮点形式的有符号位,指数和有效位数。

然而,我并不完全熟悉十六进制系统,我想知道我是否可以得到你的帮助。

到目前为止,我的想法是: 有符号位 - 按位 - 并且二进制值由0x100000000得到第一位

指数 - 将值左移一次,按位 - 并将新值移位0xFF000000以获得            指数的前八位

显着 - 将值左移23次

由于每个都需要对原始值进行处理,我还计划将值存储到另一个寄存器中。这样,我仍然可以在不“伤害”原件的情况下完成工作。然后将signed bit,exponent和signficand的值存储到单独的寄存器中。

2 个答案:

答案 0 :(得分:1)

这是一些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 

答案 1 :(得分:1)

注意:我正在处理IEEE-754单精度浮点格式以获得这个答案:

签名:使用0x80000000屏蔽您的号码。如果结果为0,则数字为正,否则为负数。 指数:使用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