BullyWiiPlaza BullyWiiPlaza - 2 months ago 16
Java Question

Hexadecimal -> Float Conversion Inaccurate

I'm using the following code to convert a hexadecimal

String
to a floating point
String
:

private static String removeScientificNotation(float value)
{
return new BigDecimal(Float.toString(value)).toPlainString();
}

/**
* Converts a hexadecimal value to its single precision floating point representation
*
* @param hexadecimal The <code>hexadecimal</code> to convert
* @return The converted value
*/
public static String hexadecimalToFloatingPoint(String hexadecimal)
{
Long longBits = Long.parseLong(hexadecimal, 16);
Float floatValue = Float.intBitsToFloat(longBits.intValue());

return removeScientificNotation(floatValue);
}


To test this, I wrote the following
JUnit
test:

public class TestConversions
{
@Test
public void testConversions()
{
String floatValue = Conversions.hexadecimalToFloatingPoint("40000000");
Assert.assertEquals(floatValue, "2.0");
floatValue = Conversions.hexadecimalToFloatingPoint("50000000");
Assert.assertEquals(floatValue, "8589934592");
floatValue = Conversions.hexadecimalToFloatingPoint("C0000000");
Assert.assertEquals(floatValue, "-2.0");
}
}


However, the 2nd assertion fails. According to various online converters like this one,
50000000
should be converted to
8589934592
but Java returns
8589934600
.

org.junit.ComparisonFailure:
Expected :8589934600
Actual :8589934592


Which result is correct now? If Java is wrong then how do I correct it?

Answer

You can achieve this by direct passing float value to BigDecimal constructor like below.Cause of problem is Float.toString(value)( As this method is make internal call to FloatingDecimal and toJavaFormatString its seems to do some rounding on values) so no need to use Float.toString instead just pass your actual float value.

    String myString = "50000000";
    Long i = Long.parseLong(myString, 16);
    Float f = Float.intBitsToFloat(i.intValue());
    String finalString= new BigDecimal(f).toPlainString();
    System.out.println("final value  "+finalString);

So just change your method like below.

private static String removeScientificNotation(float value)
{
    return new BigDecimal(value).toPlainString();
}