android不在坑三:Float丢失精度

前言:

测试:你这个平均数,怎么一下正确一下错误,你让我怎么测啊!

面对测试的怒吼,赶快灰溜溜的检查代码去了。没错啊,最后测试for循环了几次才发现,日!怎么会这样,这不是坑么

后面开发商城的时候,基本全用String来,用BigDecimal进行精确运算

当然看看测试,float是怎么丢失精度的

public class Test_1 {    public static void main(String[] args) {        System.out.println(0.06+0.01);        System.out.println(1.0-0.42);        System.out.println(4.015*100);        System.out.println(303.1/1000);    }}

运行结果如下。     0.06999999999999999     0.5800000000000001     401.49999999999994     0.30310000000000004

你认为你看错了,但结果却是是这样的。问题在哪里呢?原因在于我们的计算机是二进制的。浮点数没有办法是用二进制进行精确表示。我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。如:2.4的二进制表示并非就是精确的2.4。反而最为接近的二进制表示是 2.3999999999999999。浮点数的值实际上是由一个特定的数学公式计算得到的。

其实java的float只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。

好啦,送上大力丸工具类一枚。

public class DecimalUtil {  /**   * 金钱加法   */  public static String add(String v1, String v2) {    BigDecimal b1 = new BigDecimal(v1);    BigDecimal b2 = new BigDecimal(v2);    return b1.add(b2).toString();  }  /**   * 金钱乘法   */  public static String multiply(String v1, String v2) {    BigDecimal b1 = new BigDecimal(v1);    BigDecimal b2 = new BigDecimal(v2);     return b1.multiply(b2).toString();  }  /**   * 乘法   *   * @param v1 乘数   * @param v2 被乘数   * @param scale 小数点保留位数   */  public static String multiplyWithScale(String v1, String v2, int scale) {    BigDecimal b1 = new BigDecimal(v1);    BigDecimal b2 = new BigDecimal(v2);    BigDecimal result = b1.multiply(b2);    result = result.setScale(scale);    return result.toString();  }  /**   * 金钱除法   */  public static String divide(String v1, String v2) {    BigDecimal b1 = new BigDecimal(v1);    BigDecimal b2 = new BigDecimal(v2);    return b1.divide(b2).toString();  }  /**   * 如果除不断,产生无限循环小数,那么就会抛出异常,解决方法就是对小数点后的位数做限制   *   * @param v2 小数模式 ,DOWN,表示直接不做四舍五入,参考{@link RoundingMode}   */  public static String divideWithRoundingDown(String v1, String v2) {return divideWithRoundingMode(v1, v2, RoundingMode.DOWN);  }  /** 选择小数部分处理方式 */  public static String divideWithRoundingMode(String v1, String v2, RoundingMode roundingMode) {     return divideWithRoundingModeAndScale(v1, v2, RoundingMode.DOWN, 0);  }  /**   * 选择小数点后部分处理方式,以及保留几位小数   *   * @param v1 除数   * @param v2 被除数   * @param roundingMode 小数处理模式   * @param scale 保留几位   */  public static String divideWithRoundingModeAndScale(String v1, String v2,  RoundingMode roundingMode, int scale) {        BigDecimal b1 = new BigDecimal(v1);        BigDecimal b2 = new BigDecimal(v2);        return b1.divide(b2, scale, roundingMode).toString();  }  /**   * 金钱减法   */  public static String subtract(String v1, String v2) {    BigDecimal b1 = new BigDecimal(v1);    BigDecimal b2 = new BigDecimal(v2);    return b1.subtract(b2).toString();  }}

使用方法:

乘法:

 String countIntegral = DecimalUtil.multiply(integral, num);

加法:

    String selectedMoney = DecimalUtil.add(selectedMoney, countMoney);

结语:最后记得传入参数不能为空,即初始值要为0, String num="0",不然会报错

更多相关文章

  1. android的tone音源代码DTMF双音频何快速计算正弦波
  2. EditText保留两位小数并输入不超过最大值
  3. 基于Android的计算器(代码行数足够用来交大作业)
  4. Android(安卓)jni build 多个shared library
  5. android中editText保留小数点后两位
  6. Android使double保留两位小数的多方法 java保留两位小数
  7. 安卓简单计算器整理
  8. Android(安卓)画图 之 Matrix(一)
  9. Android实现EditText输入金额

随机推荐

  1. Android(安卓)4.4中的距离/接近传感器 P-
  2. JobIntentService与IntentService的区别
  3. Android入门笔记 - 界面开发 - ProgressD
  4. Android搜索关键字高亮显示
  5. Android音频流程二(Binder部分)
  6. Android4.2锁屏源码跟踪
  7. android如何使用自定义JNI接口,以及NDK工
  8. Android(安卓)升级Android(安卓)X 所需要
  9. android微信window.location.reload失效
  10. Android中相机,相册,剪切的原生使用