Double subtraction precision issue

后端 未结 5 2133
余生分开走
余生分开走 2020-12-05 04:49

My coworker did this experiment:

public class DoubleDemo {

      public static void main(String[] args) {
           double a = 1.435;
           double b =         


        
相关标签:
5条回答
  • 2020-12-05 05:22

    Yes it worked this way using BigDecimal operations

    private static void subtractUsingBigDecimalOperation(double a, double b) {
      BigDecimal c = BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b));
      System.out.println(c);
    }
    

    0 讨论(0)
  • 2020-12-05 05:31

    double is internally stored as a fraction in binary -- like 1/4 + 1/8 + 1/16 + ...

    The value 0.005 -- or the value 1.435 -- cannot be stored as an exact fraction in binary, so double cannot store the exact value 0.005, and the subtracted value isn't quite exact.

    If you care about precise decimal arithmetic, use BigDecimal.

    You may also find this article useful reading.

    0 讨论(0)
  • 2020-12-05 05:33

    double and float are not exactly real numbers.

    There are infinite number of real numbers in any range, but only finite number of bits to represent them! for this reason, rounding errors is expected for double and floats.

    The number you get is the closest number possible that can be represented by double in floating point representation.

    For more details, you might want to read this article [warning: might be high-level].

    You might want to use BigDecimal to get exactly a decimal number [but you will again encounter rounding errors when you try to get 1/3].

    0 讨论(0)
  • 2020-12-05 05:34

    double and float arithmetic are never going to be exactly correct because of the rounding that occurs "under the hood".

    Essentially doubles and floats can have an infinite amount of decimals but in memory they must be represented by some real number of bits. So when you do this decimal arithmetic a rounding procedure occurs and is often off by a very small amount if you take all of the decimals into account.

    As suggested earlier, if you need completely exact values then use BigDecimal which stores its values differently. Here's the API

    0 讨论(0)
  • 2020-12-05 05:38
     //just try to make a quick example to make b to have the same precision as a has, by using BigDecimal
    
     private double getDesiredPrecision(Double a, Double b){
         String[] splitter = a.toString().split("\\.");
         splitter[0].length();   // Before Decimal Count
         int numDecimals = splitter[1].length(); //After Decimal Count
    
         BigDecimal bBigDecimal = new BigDecimal(b);
         bBigDecimal = bBigDecimal.setScale(numDecimals,BigDecimal.ROUND_HALF_EVEN);
    
         return bBigDecimal.doubleValue();  
     }
    
    0 讨论(0)
提交回复
热议问题