Converting between binary and decimal representations of IEEE 754 floating-point numbers in C++, Java and Python

This post implements a previous post that explains how to convert 32-bit floating point numbers to binary numbers in the IEEE 754 format. What we have is some C++ / Java / Python routines that will allows us to convert a floating point value into it’s equivalent binary counterpart, using the standard IEEE 754 representation consisting of the sign bit, exponent and mantissa (fractional part).

Conversely, there is also a function that converts a string encoding of the IEEE 754 binary number and converts it back to a floating point value. I had been meaning to implement something like this for some time, as there are one or two applications I have in mind for which these conversions would be useful: Genetic Algorithms operating on floating point numbers for example.

Without further ado, please find code snippets and example outputs below:

C++ source code

#include <limits.h>
#include <iostream>
#include <math.h>
#include <bitset>

// Convert the 32-bit binary encoding into hexadecimal
int Binary2Hex( std::string Binary )
{
	std::bitset<32> set(Binary);		
	int hex = set.to_ulong();
	
	return hex;
}

// Convert the 32-bit binary into the decimal
float GetFloat32( std::string Binary )
{
	int HexNumber = Binary2Hex( Binary );

	bool negative  = !!(HexNumber & 0x80000000);
	int  exponent  =   (HexNumber & 0x7f800000) >> 23;	
	int sign = negative ? -1 : 1;

	// Subtract 127 from the exponent
	exponent -= 127;

	// Convert the mantissa into decimal using the
	// last 23 bits
	int power = -1;
	float total = 0.0;
	for ( int i = 0; i < 23; i++ )
	{
		int c = Binary[ i + 9 ] - '0';
		total += (float) c * (float) pow( 2.0, power );
		power--;
	}
	total += 1.0;

	float value = sign * (float) pow( 2.0, exponent ) * total;

	return value;
}

// Get 32-bit IEEE 754 format of the decimal value
std::string GetBinary32( float value )
{
	union
    {
         float input;   // assumes sizeof(float) == sizeof(int)
         int   output;
    }    data;

	data.input = value;

	std::bitset<sizeof(float) * CHAR_BIT>   bits(data.output);

	std::string mystring = bits.to_string<char, 
		                                  std::char_traits<char>,
										  std::allocator<char> >();

	return mystring;
}


int main()
{
	// Convert 19.5 into IEEE 754 binary format..
	std::string str = GetBinary32( (float) 19.5 );
	std::cout << "Binary equivalent of 19.5:" << std::endl;
	std::cout << str << std::endl << std::endl;

	// .. and back again
    float f = GetFloat32( str );
	std::cout << "Decimal equivalent of " << str << ":" << std::endl;
	std::cout << f << std::endl;

	return 0;
}

Giving us the following output:

IEEE754cpp

When float data types are unavailable

As pointed out by ‘johnsmithx’ in the comments below, what if you don’t have floats available, such as when using Meta Trader 4? Here is how to emulate it using doubles and ints, which I’ve posted here using the nice formatting that is as yet unavailable in the comments boxes:

int DoubleToBinary32(double value)
{
  int minus = 0, integer, exponent = 127, fraction = 0, i, result;

  if(value < 0) { minus = 0x80000000; value = -value; }
  integer = floor(value);
  value -= integer;
  for(i = 22; i >= 0; i--)
    {
    value += value;
    fraction += floor(value) * pow(2, i);
    value -= floor(value);
    }
  while((integer != 1) && (exponent > 0) && (exponent < 255))
    {
    if(integer > 1)
      {
      fraction = (integer&1)<<22 + fraction>>1;
      integer = integer>>1;
      exponent++;
      }
    else
      {
      integer = (fraction&0x400000)>>22;
      fraction = (fraction&0x3FFFFF)<<1;
      value += value;
      fraction += floor(value);
      value -= floor(value);
      exponent--;
      }
    }
  result = minus + exponent<<23 + fraction;
  return(result);
}

double Binary32ToDouble(int value)
{
  int minus = -1, exponent;
  double fraction, result;

  if(value&0x80000000 == 0) minus = 1;
  exponent = ((value&0x7F800000)>>23) - 127;
  fraction = value&0x7FFFFF + 0x800000;
  fraction = fraction / 0x800000;
  result = minus * fraction * pow(2, exponent);
  return(result);
}

Java source code

Of course, with Java this is all a lot simpler, since the conversions are already pretty much done for us:

public class main {
		
	// Convert the 32-bit binary into the decimal  
	private static float GetFloat32( String Binary )  
	{  
		int intBits = Integer.parseInt(Binary, 2);
		float myFloat = Float.intBitsToFloat(intBits);
	    return myFloat;  
	} 
	
	// Get 32-bit IEEE 754 format of the decimal value  
	private static String GetBinary32( float value )  
	{  
		int intBits = Float.floatToIntBits(value); 
		String binary = Integer.toBinaryString(intBits);
		return binary;
	}  	

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		// Convert 19.5 into IEEE 754 binary format..  
	    String str = GetBinary32( (float) 19.5 );  
	    System.out.println( "Binary equivalent of 19.5:" );  
	    System.out.println( str );  
	  
	    // .. and back again  
	    float f = GetFloat32( str );  
	    System.out.println( "Decimal equivalent of " + str + ":");  
	    System.out.println( f );  		
	}
}

Giving the following output:

Binary equivalent of 19.5:
1000001100111000000000000000000
Decimal equivalent of 1000001100111000000000000000000:
19.5

Python source code

Remember that in Python floats are represented by IEEE 754 floating-point format which are 64 bits long – not 32 bits.

import struct

getBin = lambda x: x > 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:]

def floatToBinary64(value):
    val = struct.unpack('Q', struct.pack('d', value))[0]
    return getBin(val)

def binaryToFloat(value):
    hx = hex(int(value, 2))   
    return struct.unpack("d", struct.pack("q", int(hx, 16)))[0]

# floats are represented by IEEE 754 floating-point format which are 
# 64 bits long (not 32 bits)

# float to binary
binstr = floatToBinary64(19.5)
print('Binary equivalent of 19.5:')
print(binstr + '\n')

# binary to float
fl = binaryToFloat(binstr)
print('Decimal equivalent of ' + binstr)
print(fl)

This gives the following console output:

Binary equivalent of 19.5:
100000000110011100000000000000000000000000000000000000000000000

Decimal equivalent of 100000000110011100000000000000000000000000000000000000000000000
19.5

For more number system conversions in C++, see this post.