8

How can I get single bits (or an entire variable) of a double or a float?

For example if I have float a = 0.5;

I would expect a String equal to:
"00111111000000000000000000000000"

or in hex:
"F000000"

glegoux
  • 3,505
  • 15
  • 32
Jan Ajan
  • 1,461
  • 3
  • 12
  • 15
  • No. Why? It is related to http://stackoverflow.com/questions/10637594/calculating-double-neighbours-of-a-decimal-value . I thought that if I subtract 1 from the binary value, I would get the other value. – Jan Ajan May 17 '12 at 21:28
  • 3
    @dcrooney asked because it's good to know whether it's homework because when it's homework we try to be careful with our answers that we don't inhibit your learning :) – kentcdodds May 17 '12 at 21:30

4 Answers4

14

For Java, a float is on 32 bits like a int, and a double is on 64 bits like a long. Finding the binary representation of these numbers, you need to:

float a = 0.5f;
int bits = Float.floatToIntBits(a);
String.format("%32s", Integer.toBinaryString(bits)).replace(" ", "0");
String.format("%8s", Integer.toHexString(bits)).replace(" ", "0");

"00111111000000000000000000000000" bit representation (32 bits)
"3f000000" hexadecimal representation (32 bits)

double a = 0.5d;
long bits = Double.doubleToLongBits(a);
String.format("%64s", Long.toBinaryString(bits)).replace(" ", "0");
String.format("%16s", Long.toHexString(bits)).replace(" ", "0");

"0011111111100000000000000000000000000000000000000000000000000000" bit representation (64 bits)
"3fe0000000000000" hexadecimal representation (64 bits)

You can check that it works by doing the reverse operation:

int bits = Integer.parseInt("00111111000000000000000000000000", 2);
Float.intBitsToFloat(bits);

0.5 (float)

long bits = Long.parseLong("0011111111100000000000000000000000000000000000000000000000000000", 2);
Double.longBitsToDouble(bits);

0.5 (double)

For the hexadecimal representation, you can use respectively Integer.parseInt("...", 16); and Long.parseLong("...", 16);

glegoux
  • 3,505
  • 15
  • 32
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • 2
    If the sign bit is zero, it wouldn't be printed! – math Nov 04 '13 at 14:42
  • 1
    @math, could you explain? Do you mean the sign bit won't be printed, or the value in its entirety? If the former, yes, `Long.toBinaryString` doesn't print extraneous bits per "This [unsigned long] value is converted to a string of ASCII digits in binary (base 2) with no extra leading 0's", but this is not unique to the sign bit. You can zero pad the value from the left to get your desired column width. – Mike Samuel Nov 04 '13 at 16:54
  • As I said, it just won't be printed, due to leading zero. Of course, one could pad this with leading zeros, but the statement above could be misinterpreted in that. And yes, if the exponent has leading zeros as well they will be cut of the same. – math Nov 04 '13 at 22:18
  • 1
    `int bits = Float.floatToIntBits(f); System.out.println(Integer.toBinaryString(bits));` works so it's almost the same code to see the bit string behind a float. – gherson Feb 21 '17 at 17:48
4

Look at Float.floatToIntBits() or Float.floatToRawIntBits(). That gets you the bits as an int. If you need it as a String, Integer.toBinaryString().

Note, there may be an issue if the HSB is on - you may need to convert to a long to avoid an "overflow".

user949300
  • 15,364
  • 7
  • 35
  • 66
  • The HSB in an IEEE-754 float is the sign bit, unless it's a NaN value, so the sign of the resulting int will be the same as that of the float, with the exception of -0.0. – Mike Samuel May 18 '12 at 15:06
  • Agreed. That comment was because some of the Java int <-> String code is fussy about the HSB. e.g. [this stackoverflow discussion](http://stackoverflow.com/questions/8888946/converting-32-bit-binary-string-with-integer-parseint-fails). Though I think it's mainly for parsing Strings, not creating them, so that issue might not apply here. – user949300 May 18 '12 at 15:32
0
public void printFloatBits(float f) {
    int bits = Float.floatToIntBits(f);
    // Extract each bit from 'bits' and compare it by '0'
    for (int i=31; i>=0; --i) {
        // int mask = 1 << i;
        // int oneBit = bits & mask;
        // oneBit == 0 or 1?
        System.out.print((bits & (1 << i)) == 0 ? "0" : "1");
    }
}
-2

Double.byteValue() might help you.

There is also a 32-bit equivalent Float.byteValue().

Pacerier
  • 86,231
  • 106
  • 366
  • 634
kentcdodds
  • 27,113
  • 32
  • 108
  • 187