Reputation: 803
I'm interested in learning how to clear bits so that I can use part of the binary value, instead of the entire thing. What I hope to use this for is to obtain the signed bit, exponent, and the significand from an IEEE single precision float form.
However, I'm not entirely familiar with the hexadecimal system, and I was wondering if I could get your help.
Here are my thoughts so far: Signed bit - Bitwise-AND the binary value by 0x100000000 to get the first bit only
Exponent - Shift the value left once, and bitwise-and the new value by 0xFF000000 to obtain the first eight bits for the exponent
Significand - Shift the value left 23 times
Since each of these will require doing work on the original value, I'm planning to also store the value into another register. That way, I can still do work on the value without "harming" the original. The value of the signed bit, exponent, and the signficand will then be stored into separate registers.
Upvotes: 2
Views: 3052
Reputation: 1036
In java, Bitwise XOR operation can be used to clear bit. You can convert a specific from String to Integer using
I have written this function to clear the leftmost bit, irrespective of the sign.
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= %d\n 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;
}
Upvotes: 1
Reputation: 21086
Here's some NASM syntax 32bit
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
In C it would be something like
int sign = value & 0x80000000;
int expo = value & 0x7F800000;
int sigf = value & 0x007FFFFF;
sign >>= 31;
expo >>= 23;
EDIT if you want to correct the exponent which has a 127 (7Fh) bias
if(expo == 0x0) {
// denormal
} else if(expo == 0xFF) {
// +inf or nan depending on sigf
} else { // -126 to 127 range
expo -= 0x7F;
}
EDIT 2 In other languages like Java ">>" is a signed shift operator.
sign >>= 31; // would result in 0 or -1 (0xFFFFFFFF) if the sign bit was 1
sign >>>= 31; // would result in 0 or 1
Upvotes: 2
Reputation: 11428
NOTE: I'm dealing with IEEE-754 single precission floating point format for this answer:
Sign: AND-mask your number with 0x80000000
. If result is 0, number is positive, else negative.
Exponent: AND-mask your number with 0x7F800000
, then shift 23 bits to the right.
Mantissa: AND-mask your number with 0x007FFFFF
.
To see why I have used these numbers, just convert each mask to binary form and place it under your binary representation of your floating point number:
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)
To convert a binary number to hexadecimal, just arrange it in 4-bit groups and convert each group to an hexadecimal digit:
For example:
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
Upvotes: 3