Java Double相加出现的怪事
来源:互联网 发布:淘宝首页分类导航代码 编辑:程序博客网 时间:2024/06/06 15:37
最近项目中有个抽奖概率的配置,前台配置的概率相加明明等于100,存入数据库的时候报错了.debug发现doule类型相加后不等于100.
这里有个小知识:
Java中的简单浮点数类型float和double不能够进行运算。不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,但是多试几次(可以做一个循环)就可以试出类似上面的错误。现在终于理解为什么要有BCD码了.这个问题相当严重,如果你有9.999999999999元,你的计算机是不会认为你可以购买10元的商品的。
在有的编程语言中提供了专门的货币类型来处理这种情况,但是Java没有。现在让我们看看如何解决这个问题。
解决方案
现在我们已经可以解决这个问题了,原则是使用BigDecimal并且一定要用String来够造。
但是想像一下吧,如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。你能够忍受这么烦琐的过程吗?下面我们提供一个工具类Arith来简化操作。它提供以下静态方法,包括加减乘除和四舍五入:
public class Arith { // 源文件Arith.java: /** * 由于Java的简单类型不能够精确的对浮点数进行运算, * 这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入。 */ // 默认除法运算精度 private static final int DEF_DIV_SCALE = 10; // 这个类不能实例化 private Arith() { } /** * 提供精确的加法运算。 * * @param v1 * 被加数 * @param v2 * 加数 * @return 两个参数的和 */ public static double add(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算。 * * @param v1 * 被减数 * @param v2 * 减数 * @return 两个参数的差 */ public static double sub(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算。 * * @param v1 * 被乘数 * @param v2 * 乘数 * @return 两个参数的积 */ public static double mul(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。 * * @param v1 * 被除数 * @param v2 * 除数 * @return 两个参数的商 */ public static double div(double v1, double v2) { return div(v1, v2, DEF_DIV_SCALE); } /** * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。 * * @param v1 * 被除数 * @param v2 * 除数 * @param scale * 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static double div(double v1, double v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精确的小数位四舍五入处理。 * * @param v * 需要四舍五入的数字 * @param scale * 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double v, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); }}
阅读全文
0 0
- java double相加出现的怪事
- Java Double相加出现的怪事
- Java Double相加出现的怪事
- Java Double相加出现的怪事
- Java Double相加出现的怪事
- Java Double相加出现的怪事
- Java Double相加出现的怪事
- Java Double相加出现的怪事
- Java Double相加出现的怪事
- Java Double相加出现的怪事
- java中double类型相加出现的怪事
- 【转】Java double 相加的怪事情
- java中的double相加的怪事
- double相加的出现的错误
- java中Double数据相加的处理
- 关于java中double相加的问题
- java Double类型的数字相加
- JAVA double 类型相加
- struts2入门--工作流程
- POJ 3080 Blue Jeans (分解字符串,KMP)
- [(ngModel)]的实现原理
- Jzzhu and Sequences
- 干货分享:oracle数据库基础知识精讲视频!
- Java Double相加出现的怪事
- B
- 零基础学习嵌入式:嵌入式linux视频教程免费分享!
- 无人机项目我的关注angularjs逻辑
- [BZOJ]1187: [HNOI2007]神奇游乐园 插头DP
- 20.odoo入门——杂记
- Linux系统安装wireshark
- hive中order by,distribute by,sort by,cluster by
- 修饰符在python函数中的用法详细解释