Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Range of Float in Java

I have been trying the following code in Java :

import java.math.*;

public class trial {

public static void main(String[] args) {

    // create a BigDecimal object
    BigDecimal bg;

    // create a Float object
    Float f;
    float f2 = 35912062;
    bg = new BigDecimal(35912062);

    // assign the converted value of bg to f
    f = bg.floatValue();

    String str = "Float value of " + bg + " is " + f;

    bg = new BigDecimal(f);
    String str2 = "BigDecimal value of " + bg;


    // print f value
    System.out.println( str );
    System.out.println( str2 );
    System.out.println( 35912062f );
    System.out.println(f2);
}
}

So, the following is the output I am getting :

    Float value of 35912062 is 3.5912064E7
    BigDecimal value of 35912064
    3.5912064E7
    3.5912064E7

Now, I believe that it is because this is extending the range of float but when I read this : What is the inclusive range of float and double in Java?

it shows the inclusive range of float to be : 3.40282346638528860e+38

This has made me really confused. Any links giving explanations will help.

EDIT: Say I take 25912062 inplace of 35912062, The output for 25912062 is 25912062, but for, 35912062 the output is 35912064 why is this so ?

like image 520
Kartavya Ramnani Avatar asked Aug 29 '17 09:08

Kartavya Ramnani


1 Answers

Basically, floating point values are stored as a pair of mantissa and exponent. The mantissa describes the significant digits of the number (think of it as a number between 0 and 9.99). The exponent is the scale. Your number is presented as mantissa * 2^x.

We are talking about a representation in the binary system, which makes even straight numbers (in the decimal system) like 35912062 to something which may not exactly fit within the precision of the mantissa. In these cases, you get some rounding issues, especially as float has a rather limited range for the mantissa.

Executing your code with double (instead of float) gives you 3.5912062E7 as result.

If your really wanna know what java (or the floating point arithmetic) makes of your number, you should do System.out.println(new Bigdecimal(123.456)) and be surprised.

The message here is, if you really need precise arithmetics always take BigDecimal. Because there are further caveats. For example, adding a large double and a small double may result in the small double to be rounded away completely. That takes us to a funny thing:

    for (float f = 35912062f; f < 55912062f; f++) {
        System.out.println(f);
    }

will never terminate. Just try it.

like image 63
Jonathan Avatar answered Sep 20 '22 16:09

Jonathan