前几天看了一个朋友的博客,说Java中浮点数运算精度丢失的问题,他给出了问题,也指出了C语言相对于Java的优势,其实,Java中也是可以解决浮点运算精度丢失问题的。
那就是:BigDecimal。
先看一段程序:
public class DoubleTest { public static void main(String args[]) { System.out.println("0.05 + 0.01 = " + (0.05 + 0.01)); System.out.println("1.0 - 0.42 = " + (1.0 - 0.42)); System.out.println("4.015 * 100 = " + (4.015 * 100)); System.out.println("123.3 / 100 = " + (123.3 / 100)); } }
上面的程序运行结果是:
上面程序运行结果表明,Java的double类型会发生精度丢失问题,其实,不尽是Java,很多编程语言都存在这样的问题。
为了能精确的表示、计算浮点数,Java提供了BigDecimal类,该类提供了大量的构造器用于创建BigDecimal对象,包括把所有的基本类型转换层一个BigDecimal对象,也包括利用数字字符串、数字字符数组来创建BigDecimal对象。详细介绍请查阅API手册。
双精度浮点型变量 double 可以处理 16 位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。 Java 在 java.math 包中提 供的 API 类 BigDecimal ,用来对超过 16 位有效位的数进行精确的运算。表 5.7 中列出了 BigDecimal 类的主要构造器和方法。
构造器描述 :
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。
方法描述 :
add(BigDecimal)BigDecimal 对象中的值相加,然后返回这个对象。
subtract(BigDecimal)BigDecimal 对象中的值相减,然后返回这个对象。
multiply(BigDecimal)BigDecimal 对象中的值相乘,然后返回这个对象。
divide(BigDecimal)BigDecimal 对象中的值相除,然后返回这个对象。
toString() 将 BigDecimal 对象的数值转换成字符串。
doubleValue() 将 BigDecimal 对象中的值以双精度数返回。
示例程序:
public class BigDecimalTest { public static void main(String[] args) { BigDecimal f1 = new BigDecimal("0.05"); BigDecimal f2 = BigDecimal.valueOf(0.01); BigDecimal f3 = new BigDecimal(0.05); System.out.println("使用String作为BigDecimal构造器参数:"); System.out.println("0.05 + 0.01 = " + f1.add(f2)); System.out.println("0.05 - 0.01 = " + f1.subtract(f2)); System.out.println("0.05 * 0.01 = " + f1.multiply(f2)); System.out.println("0.05 / 0.01 = " + f1.divide(f2)); System.out.println("使用double作为BigDecimal构造器参数:"); System.out.println("0.05 + 0.01 = " + f3.add(f2)); System.out.println("0.05 - 0.01 = " + f3.subtract(f2)); System.out.println("0.05 * 0.01 = " + f3.multiply(f2)); System.out.println("0.05 / 0.01 = " + f3.divide(f2)); } }
程序运行结果:
从上面的运行结果可以看出,BigDecimal进行算术运算的效果,而且,在创建BigDecimal对象时,一定要使用String对象作为构造器参数,而不是直接使用double数字。
API手册中是这样解释的:
注:
public BigDecimal(double val)
- 此构造方法的结果有一定的不可预知性。有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为 double (或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样, 传入 到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
- 另一方面, String 构造方法是完全可预知的:写入 new BigDecimal("0.1") 将创建一个 BigDecimal ,它 正好 等于预期的 0.1。因此,比较而言,通常建议优先使用 String 构造方法 。
- 当 double 必须用作 BigDecimal 的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用
Double.toString(double)
方法,然后使用BigDecimal(String)
构造方法,将 double 转换为 String 。要获取该结果,请使用 staticvalueOf(double)
方法。
http://www.tuicool.com/articles/nAFr6r
相关推荐
浮点数在计算机内部是以二进制表示的,这与我们通常使用的十进制系统不同,因此在进行浮点数运算时可能会出现精度丢失的问题。这篇博客主要探讨了Java中浮点数(包括`float`和`double`类型)运算的特性、存在的问题...
虽然 `double` 提供了相对较高的精度,但在涉及精确数学运算(特别是涉及到小数值)时,由于其内部采用二进制浮点数格式存储,仍会出现精度丢失的情况。这种精度丢失的现象对于需要高精度计算的应用来说是一个常见的...
2. 控制浮点数运算的精度:在某些情况下,我们可能不需要非常高的精度,可以通过设置`DecimalFormat`或者`printf`格式化输出来控制显示的位数,从而达到视觉上看似精确的效果。 3. 使用`BigInteger`处理整数部分:...
JS 数字精度丢失的一些典型问题 JS 数字精度丢失的原因 解决方案(一个对象+一个函数) 一、JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加 0.1 + 0.2 != 0.3 // true 这真不是 Firebug 的问题,可以用...
1. **使用BigDecimal类**:Java提供了`java.math.BigDecimal`类,用于进行高精度的浮点数运算。它允许指定精度,并在计算过程中保持该精度,从而避免了浮点数的精度问题。 2. **比较浮点数时的容差**:直接比较两个...
解决java数值范围以及float与double精度丢失的问题 Java中的数值范围和浮点数精度问题是许多开发者经常遇到的问题。下面我们将详细探讨Java中的数值范围、float和double类型的精度问题,并且提供解决方案。 一、...
在编程领域,浮点数计算由于涉及到二进制表示法,常常会出现精度丢失的问题,这在需要精确计算的场景下尤为棘手。Java作为一种广泛使用的编程语言,也面临同样的挑战。为了解决这个问题,我们可以利用特定的设计和...
BigDecimal类是一个大小数操作类,可以用来对超过16位有效位的数据进行精确的运算,在这里我们使用BigDecimal类来解决浮点数计算产生的精度丢失问题。 精度问题 在这里我们讨论一个问题:3 – 2.7 == 0.3 的值是什么...
然而,由于浮点数的二进制表示方式,当进行某些计算或转换时,可能会出现精度丢失的问题。标题提到的“double类型精度丢失;double转换到64位整数”就涉及到这一关键概念。 精度丢失通常发生在以下几种情况: 1. *...
在Java编程中,使用`float`和`double`类型进行浮点数计算时经常会遇到精度丢失的问题。这是因为浮点数在计算机内部是以二进制形式存储的,而某些十进制小数无法用二进制精确表示,从而导致计算结果出现误差。例如,`...
java运算工具类,可以处理浮点数的精度丢失问题,可以实现精确计算,常用公共方法抽取,常用工具类11111111111111111111111111111111111111111111111111111111111111111111111111
Java 中的双精度浮点数(double)类型在进行运算时经常出现精度丢失的问题,这是由于双精度浮点数在计算机内部的存储方式所致。双精度浮点数使用 64 位二进制数来存储小数,然而这种存储方式会导致某些小数无法精确...
`BigDecimal`类可以用来表示和操作精确的十进制数值,避免了浮点数运算中的精度问题。在`ThtBigDecimal.java`这个文件中,很可能包含了一个示例或者工具类,展示了如何使用`BigDecimal`进行精确计算。 使用`...
同时,在处理非常小的数值时,确保不小于`float`或`double`的最小值,可以防止因为数值过小而导致的精度丢失。 此外,浮点数的比较也需要注意,由于浮点数的不精确性,直接使用`==`进行比较可能会导致错误的结果。...
### DecimalFormat精度解决与商业运算精度问题 在进行财务计算或者商业运算时,精度问题往往成为影响最终结果准确性的关键因素之一。特别是在Java这样的语言环境中,由于其内部采用二进制浮点数表示小数的方式,这...
本文主要探讨的是“计算机精度问题”,特别是关于双精度浮点数(Double)的表示和计算中可能出现的问题。 双精度浮点数(Double)在计算机中通常按照IEEE 754标准进行存储和运算,它提供了大约15到16位的有效数字,...
10. 浮点数运算精度问题:需要注意的是,虽然使用了double类型表示身高,但浮点数运算可能引入精度问题。在金融或科学计算中,这种情况可能需要使用BigDecimal等类来避免精度丢失。 通过这个Java练习题,学习者不仅...
常见问题还包括在进行浮点数运算时可能出现的精度丢失,以及在设计数据库表结构时选择合适的数据类型。例如,如果业务逻辑要求精确存储和计算小数,那么选择DECIMAL而非FLOAT或DOUBLE会更为合适。 总的来说,理解和...
由于基本数据类型`double`和`float`在进行大数值或高精度计算时可能会导致精度丢失,因此`BigDecimal`被设计出来解决这个问题。它提供了一种可控的精度计算方式,可以避免因为浮点数运算引发的不精确问题。 1. `...
3. **浮点数运算**:JAVA的浮点数运算涉及到double和float类型,它们可以进行更精确的小数运算。例如,`double d = 4.5 / 2.0;` 结果d将是2.25。 4. **运算符优先级**:JAVA中的运算符有不同的优先级,例如括号最高...