What's the right way to parseFloat in Java

后端 未结 7 1755
[愿得一人]
[愿得一人] 2021-01-12 01:52

I notice some issues with the Java float precision

       Float.parseFloat(\"0.0065\") - 0.001  // 0.0055000000134110451
       new Float(\"0.027\") - 0.001          


        
相关标签:
7条回答
  • 2021-01-12 02:09

    I would convert your float to a string and then use BigDecimal.

    This link explains it well

    new BigDecimal(String.valueOf(yourDoubleValue));
    

    Dont use the BigDecimal double constructor though as you will still get errors

    0 讨论(0)
  • 2021-01-12 02:22

    See What Every Computer Scientist Should Know About Floating-Point Arithmetic. Your results look correct to me.

    If you don't like how floating-point numbers work, try something like BigDecimal instead.

    0 讨论(0)
  • 2021-01-12 02:26

    The problem is simply that float has finite precision; it cannot represent 0.0065 exactly. (The same is true of double, of course: it has greater precision, but still finite.)

    A further problem, which makes the above problem more obvious, is that 0.001 is a double rather than a float, so your float is getting promoted to a double to perform the subtraction, and of course at that point the system has no way to recover the missing precision that a double could have represented to begin with. To address that, you would write:

    float f = Float.parseFloat("0.0065") - 0.001f;
    

    using 0.001f instead of 0.001.

    0 讨论(0)
  • 2021-01-12 02:28

    From the Java Tutorials page on Primitive Data Types:

    A floating-point literal is of type float if it ends with the letter F or f; otherwise its type is double and it can optionally end with the letter D or d.

    So I think your literals (0.001) are doubles and you're subtracting doubles from floats.

    Try this instead:

    System.out.println((0.0065F - 0.001D)); // 0.005500000134110451
    System.out.println((0.0065F - 0.001F)); // 0.0055
    

    ... and you'll get:

    0.005500000134110451
    0.0055
    

    So add F suffixes to your literals and you should get better results:

    Float.parseFloat("0.0065") - 0.001F
    new Float("0.027") - 0.001F
    Float.valueOf("0.074") - 0.001F
    
    0 讨论(0)
  • 2021-01-12 02:29

    Floating point cannot accurately represent decimal numbers. If you need an accurate representation of a number in Java, you should use the java.math.BigDecimal class:

    BigDecimal d = new BigDecimal("0.0065");
    
    0 讨论(0)
  • 2021-01-12 02:30

    You're getting the right results. There is no such float as 0.027 exactly, nor is there such a double. You will always get these errors if you use float or double.

    float and double are stored as binary fractions: something like 1/2 + 1/4 + 1/16... You can't get all decimal values to be stored exactly as finite-precision binary fractions. It's just not mathematically possible.

    The only alternative is to use BigDecimal, which you can use to get exact decimal values.

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