Java数值计算精度问题

  1. 1. Double
  2. 2. BigDecimal
  3. 3. 数值溢出问题

1. Double

System.out.println(0.1+0.2);
System.out.println(1.0-0.8);
System.out.println(4.015*100);
System.out.println(123.3/100);

double amount1 = 2.15;
double amount2 = 1.10;
if (amount1 - amount2 == 1.05)
    System.out.println("OK");

// Output 
0.30000000000000004
0.19999999999999996
401.49999999999994
1.2329999999999999

上述问题出现的原因是因为计算机是以二进制存储数值的,浮点数也是如此。 Java采用的是IEEE754标准来实现浮点数的表达和运算,当将一个10进制的数值转化成浮点数的时候,会出现无限循环的结果。当使用二进制表示是无限循环的时候,转换成10进制就会造成精度的缺失了。

2. BigDecimal

BigDecimal可以用于浮点数精确表达的场景,但是使用BigDecimal的时候,一定要注意使用字符串的构造方法来初始化

System.out.println(new BigDecimal("0.1").add(new BigDecimal("0.2")));
System.out.println(new BigDecimal("1.0").subtract(new BigDecimal("0.8")));
System.out.println(new BigDecimal("4.015").multiply(new BigDecimal("100")));
System.out.println(new BigDecimal("123.3").divide(new BigDecimal("100")));


0.3
0.2
401.500
1.233
  • BigDecimal

    • 有scale, Precision的概念
    • scale 表示小数点右边的位数
    • precision 表示精度,即有效数字的长度
  • BigDecimal的equals判等

    • 比较的是value和scale 两个值的!
System.out.println(new BigDecimal("1.0").equals(new BigDecimal("1")))

false
/**
 * Compares this {@code BigDecimal} with the specified
 * {@code Object} for equality.  Unlike {@link
 * #compareTo(BigDecimal) compareTo}, this method considers two
 * {@code BigDecimal} objects equal only if they are equal in
 * value and scale (thus 2.0 is not equal to 2.00 when compared by
 * this method).
 *
 * @param  x {@code Object} to which this {@code BigDecimal} is
 *         to be compared.
 * @return {@code true} if and only if the specified {@code Object} is a
 *         {@code BigDecimal} whose value and scale are equal to this
 *         {@code BigDecimal}'s.
 * @see    #compareTo(java.math.BigDecimal)
 * @see    #hashCode
 */
@Override
public boolean equals(Object x)

3. 数值溢出问题

所有的基本数值类型都有超出表达范围的可能性,而且是没有任何异常的默默的溢出

  • 可以使用Math类的addExact, substractExact等方法进行数值运算,在溢出的时候主动抛出异常
  • 也可以使用BigInteger,也会主动抛出异常

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 stone2paul@gmail.com

文章标题:Java数值计算精度问题

文章字数:527

本文作者:Leilei Chen

发布时间:2020-08-31, 22:29:02

最后更新:2020-08-31, 22:29:27

原始链接:https://www.llchen60.com/Java%E6%95%B0%E5%80%BC%E8%AE%A1%E7%AE%97%E7%B2%BE%E5%BA%A6%E9%97%AE%E9%A2%98/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏