2
votes

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.

2
Ideally you want to shift right not left, but you are on the right track, mask and shift (AND and shift) is how you do it. or shift then and whatever you prefer, does the same thingold_timer
It is very obvious that you are breaking the problem down into individual parts and asking how to do each thing on stackoverflow, and that is the right way to use stackoverflow. I would highly recommend you do whatever it is you are doing in a language like C first (assuming you know C and it is something easier to write in) on your development machine, get all of your masking and shifting and other bit manipulation done, develop anywhere, run anywhere. Once it performs the task properly then using that prototype then simply implement that code in assembly language.old_timer
Just a note: to get the most significant bit only, you should AND the value by 0x80000000.Pietro Lorefice
Ideally simplifying the C code down to single operations, and/or operations that directly translate to single or a few lines of asm.old_timer
Also, I think it would be worth your time to bone up on the relationship of hexadecimal to bits. Get some graph paper, and draw out what you intend to do. Each hexadecimal digit corresponds to 4 consecutive bits, so mark "tick" marks every four bits. Once you have your "map" on paper, it should be easy to see how mask values in hex map onto the fields in your number. It'll save you time in the long run.Joe Z

2 Answers

1
votes

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
1
votes

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