java 小心使用float和double他可能不如你所想

Posted 听哥哥的话

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 小心使用float和double他可能不如你所想相关的知识,希望对你有一定的参考价值。

    public static void main(String[] args) {
      double funds=1.00;
      int itemBought=0;
      //
        double price=.1;
      for(price=.1;funds>=price;price+=.10){
         funds-=price;
         itemBought++;
      }
      //#解释1
         // 第一次 price=0.1 funds=1.00
        //             #1            #2          #3
        // for(double price=.1;funds>=price;price+=.10)
        //不经过#2,#3 price仍然为0.1 进入for循环 执行 funds-=prcie 此时funds=1 ,price=0.1 ,结果funds=0,9
        // 第二次 执行#3 price+=0.1 得price=0.2 再执行#2 funds>=price 此时funds=0.9,price=0.2,结果为true 进入for循环 funds-=price 得funds=0.7
        // 第三次 执行#3 price+=0.1 得price=0.30000000000000004 在执行#2 funds>=price 此时funds=0.7,price=0.30000000000000004(开始误差了) 结果为true 进入for循环 funds-=price 得 funds=0.3999999999999999
        // 第四次 执行# price+=0.1 得price=0.4 再执行#2 funds>=price 此时funds=0.3999999999999999 ,price=0.4,结果为false 不进入循环体 所以itemBought结果为3
      //#解释1
        
      System.out.println(itemBought+" items bought.");
      System.out.println("change:$"+funds);
    }

对于误差解决办法是使用 BigDecimal,int或long进行货币计算,int和long涉及数值大小,
BigDecimal则用于对精度要求比较高的场合,下面我们使用BigDecimal写了个简单代码

package com.hra.riskprice;

import com.hra.riskprice.SysEnum.Factor_Type;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.math.BigDecimal;
import java.util.*;
@SpringBootApplication
public class RiskpriceApplication {

    public static void main(String[] args) {
      final BigDecimal TEN_CENTS=new BigDecimal(".10");

      int itemBought=0;

      BigDecimal funds=new BigDecimal("1.00");

      for(BigDecimal price=TEN_CENTS;funds.compareTo(price)>=0;price=price.add(TEN_CENTS)){

          funds=funds.subtract(price);
         itemBought++;

      }

      System.out.println(itemBought+" items bought.");
      System.out.println("change:$"+funds);
    }
}
for循环什么执行的就不分析了,自己调试下加深映像就好,通常for的执行顺序都是如此,感谢观摩

 

以上是关于java 小心使用float和double他可能不如你所想的主要内容,如果未能解决你的问题,请参考以下文章

Java double和 float丢失精度问题

Java面试官:兄弟,你确定double精度比float低吗?

关于java的double类型和float类型

Java中的简单浮点数类型float和double不能够进行精确运算

java float double精度为啥会丢失

在java中的double和float类型数据相除为啥可以除以零