Extracting numbers from a 32-bit integer
I'm trying to solve a riddle in a programming test.
Disclaimer: It's a test for a job, but I'm not looking for an answer. I'm just looking for an understanding of how to do this. The test requires that I come up with a set of solutions to a set of problems within 开发者_如何学C2 weeks, and it doesn't state a requirement that I arrive at the solutions in isolation.
So, the problem:
I have a 32-bit number with the bits arranged like this:
siiiiiii iiiiiiii ifffffff ffffffff
Where:
- s is the sign bit (1 == negative)
- i is 16 integer bits
- f is 15 fraction bits
The assignment is to write something that decodes a 32-bit integer into a floating-point number. Given the following inputs, it should produce the following outputs:
input output
0x00008000 1.0
0x80008000 -1.0
0x00010000 2.0
0x80014000 -2.5
0x000191eb 3.14
0x00327eb8 100.99
I'm having no trouble getting the sign bit or the integer part of the number. I get the sign bit like this:
boolean signed = ((value & (1 << 31)) != 0);
I get the integer and fraction parts like this:
int wholePart = ((value & 0x0FFFFFFF) >> 15);
int fractionPart = ((value & 0x0000FFFF >> 1));
The part I'm having an issue with is getting the number in the last 15 bits to match the expected values. Instead of 3.14, I get 3.4587, etc.
If someone could give me a hint about what I'm doing wrong, I'd appreciate it. More than anything else, the fact that I haven't figured this out after hours of messing with it is kind of driving me nuts. :-)
Company's inputs aren't wrong. The fractional bits don't represent the the literal digits right of the decimal point, they represent the fractional part. Don't know how else to say it without giving it away. Would it be too big a hint to say there is a divide involved?
A few things...
Why not get the fractional part as
int fractionPart = value & 0x00007FFF; // i.e. no shifting needed...
Similarly, no shifting needed for the sign
boolean signed = ((value & (0x80000000) != 0); // signed is true when negative
See Ryan's response for the effective use of the fractional part, i.e. not taking this literally as the digit values for the decimal part but rather... some' involving a fraction...
Have a look at what you're anding the fraction part with prior to the shift.
Shift Right 31 gives you the signed bit 1=Neg 0=Pos
BEFORE siiiiiii iiiiiiii ifffffff ffffffff SHR 31 00000000 00000000 00000000 0000000s
Shift Left 1 followed by Shift Right 16 gives you the Integer bits
BEFORE siiiiiii iiiiiiii ifffffff ffffffff SHL 1 iiiiiiii iiiiiiii ffffffff fffffff0 SHR 16 00000000 00000000 iiiiiiii iiiiiiii
Shift Left 17 followed by Shift Right 15 gives for the Faction bits
BEFORE siiiiiii iiiiiiii ifffffff ffffffff SHL 17 ffffffff fffffff0 00000000 00000000 SHR 16 00000000 00000000 0fffffff ffffffff
int wholePart = ((value & 0x7FFFFFFF) >> 15);
int fractionPart = (value & 0x00007FFF);
Key your bit-mask into Calculator in Binary mode and then flip it to Hex...
精彩评论