Precision lost in float value using java

后端 未结 5 1109
醉酒成梦
醉酒成梦 2020-12-03 16:15

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?

相关标签:
5条回答
  • 2020-12-03 16:48

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

    0 讨论(0)
  • 2020-12-03 16:51

    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.

    0 讨论(0)
  • 2020-12-03 16:53

    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/

    0 讨论(0)
  • 2020-12-03 17:01

    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))

    0 讨论(0)
  • 2020-12-03 17:03

    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.

    0 讨论(0)
提交回复
热议问题