tags:

views:

199

answers:

5

Hi,

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 2 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. :-)

A: 
int wholePart = ((value & 0x7FFFFFFF) >> 15);

int fractionPart = (value & 0x00007FFF);

Key your bit-mask into Calculator in Binary mode and then flip it to Hex...

Cade Roux
+1  A: 

Have a look at what you're anding the fraction part with prior to the shift.

Dave Barker
+2  A: 

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...

mjv
+4  A: 

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?

ryan
Oh. I'm fired...
Jed Smith
To 5 decimal places, that's correct (and the given values print accurately at 5 decimal places as above with 3 extra zeroes). A 15-bit fraction gives approximately 0.00003 (1 / 32K) per count, so 4 or 5 decimal places are reasonable.
Jonathan Leffler
A: 

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

Cape Cod Gunny