Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 763
BullyWiiPlaza Avatar asked Sep 13 '16 08:09

BullyWiiPlaza


1 Answers

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();
}
like image 168
Jekin Kalariya Avatar answered Oct 22 '22 20:10

Jekin Kalariya