user1355253
user1355253

Reputation: 95

Precision lost in float value using java

Given below the test code and its output. When I get float value from number value, precision is lost.. Can anyone tell me why this behaviour and also how to handle this?

public static void main(String[] args)
    {
        try
        {
            java.lang.Number numberVal = 676543.21;
            float floatVal = numberVal.floatValue();
            System.out.println("Number value    : " + numberVal);
            System.out.println("float value     : " + floatVal);
            System.out.println("Float.MAX_VALUE : " + Float.MAX_VALUE);
            System.out.println("Is floatVal > Float.MAX_VALUE ? " + ( floatVal > Float.MAX_VALUE));
        }catch(Exception e)
        {
            e.printStackTrace();
        }
    }

output:

    Number value    : 676543.21
    float value     : 676543.2
    Float.MAX_VALUE : 3.4028235E38
    Is floatVal > Float.MAX_VALUE ? false

also why the float value lesser than Float.MAX_VALUE?

Upvotes: 5

Views: 31431

Answers (5)

Tassos Bassoukos
Tassos Bassoukos

Reputation: 16142

floats are usually good up to 6 significant digits. Your number is 676543.21 which has 8 significant digits. You will see errors past 6 digits, and those errors will easily propagate to more significant digits the more calculations you perform. If you value your sanity (or precision), use doubles. Floats can't even count past 10 million accurately.

Now, you have 2 significant digits, which suggests to me that there is a chance you want to represent currency - DO NOT . Use your own class that internally represents values using fixed-point arithmetic.

Now, as to Float.MAX_VAL which is 3.4028235E38, meaning 3.4028235*10^38 which is about 10^32 times larger than your value. Notice the 'E' in there? That's the exponent.

Upvotes: 26

James
James

Reputation: 2542

Decimal literals like the one you have typed default to type double, not float. java.lang.Number also uses doubles by default. If you were to replace that with java.lang.Number numberVal = 676543.21f; I would expect the same level of precision loss from both. Alternatively, replace float floatVal = numberVal.floatValue(); with double doubleVal = numberVal.doubleValue(); In order not to lose precision.

EDIT, as an example, try running:

Number num = 676543.21;
System.out.println(num); //676543.21
System.out.println(num.doubleValue()); //676543.21
System.out.println(num.floatValue()); //676543.2 <= loses the precision

to see the difference in precision of the types

Float.MAX_VALUE returns the largest value that a float can ever hold. any higher will overflow. If you look carefully, you'll see an 'E' in its textual representation. This is standard index form, that 'E' means "multiply by 10 to the power of whatever number follows the E" (or in java-speak *pow(10, numberAfterE))

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533442

All data types have representation limits so the fact there is a limit shouldn't be surprising.

float uses 24-bit for its "mantissa" which holds all the significant digits. This means it has about 7 digits of precision (as 2^^24 is about 16 million)

double uses 53-bit for it "mantissa" so it can hold about 16 digits accurately.

Upvotes: 9

Shark
Shark

Reputation: 6610

I love these. But I'll make it quick and painless.

Floats and decimals (aka floating points) aren't kept in the memory precisely either. But I don't want to get into float accuracy vs precision issues here, i'll just point you to a link - http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

As far as your other question, lemme put it this way, since floats are stored in scientific notation.

floatVal = 6.765432E6 = 6.7 * 10^6
MAX_VALUE = 3.4E38 = 3.4 * 10^38

MAX_VALUE is 32 orders of magnitude bigger than your float number. Feel free to take a look at here as well http://steve.hollasch.net/cgindex/coding/ieeefloat.html

I've spent a great deal of time comparing and fixing some FP issues a few months ago...

Try to use a small delta when comparing floats. Maybe this link will help you http://introcs.cs.princeton.edu/java/91float/

Upvotes: 9

jontro
jontro

Reputation: 10628

3.4028235E38 is greater than 676543.2. Float.MAX_VALUE is the largest float that is possible to represent.

Upvotes: 2

Related Questions