BigDecimal代替浮点数精确计算用法简介

简介: 浮点数浮点数是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学计数法。浮点计算是指浮点数参与的运算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。一个浮点数a由两个数m和e来表示:a = m × b^e。在任意一个这样的系统中,我

浮点数

浮点数是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学计数法。

浮点计算是指浮点数参与的运算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。
一个浮点数a由两个数m和e来表示:a = m × b^e。在任意一个这样的系统中,我们选择一个基数b(记数系统的基)和精度p(即使用多少位来存储)。m(即尾数)是形如±d.ddd...ddd的p位数(每一位是一个介于0到b-1之间的整数,包括0和b-1)。如果m的第一位是非0整数,m称作规格化的。有一些描述使用一个单独的符号位(s 代表+或者-)来表示正负,这样m必须是正的。e是指数。


BigDecimal

在Java中,float声明的变量是单精度浮点数,double声明的变量是双精度浮点数,顾名思义就是double型的实体占用内存空间是float的两倍。float是4个字节而double是8个字节。float和double类型的数据,无法精确表示计算结果,这是由于float和double是不精确的计算。大家可以通过下面代码可以看出来:

public class Test{  
  public static void main(String[] args)  
    {    
    System.out.println(0.05 + 0.01);   
     System.out.println(1.0 - 0.42);   
      System.out.println(4.015 * 100);    
      System.out.println(123.3 / 100);   
       }
      }


运行的结果为:
0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
要想获得理想的结果,我们可以考虑使用BigDecimal来获得更精确的计算:
BigDecimal提供了多个构造函数,和浮点数有关的有:
BigDecimal(double val)  Translates a double into a BigDecimal.
BigDecimal(String val) Translates the String repre sentation of a BigDecimal into a BigDecimal.
但是用double参数来创建对象得到不精确的值,只有通过String来创建对象才是最准确的。
例如:
BigDecimal data1=new BigDecimal(0.05);
System.out.println(data1.toString());
BigDecimal data2=new BigDecimal("0.05");
System.out.println(data2.toString());
得到结果:
0.05000000000000000277555756156289135105907917022705078125
0.05
所以,我们最终需要使用String来创建对象,这样得到的结果才是最精确的。另外,如果是double数,我们还可以使用:BigDecimal.valueOf(double val),原因很简单,其JDK源码如下所示:

public static BigDecimal valueOf(double val)
{ 
   return new BigDecimal(Double.toString(val));
 }

最后需要说明的是:BigDecimal的加减乘除其实最终都返回的是一个新的BigDecimal对象,因为BigDecimal是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,所以a.add(b);虽然做了加法操作,但是a并没有保存加操作后的值,正确的用法应该是a=a.add(b)。


参考文章:

http://swiftlet.net/archives/798

 

本文出自 “点滴积累” 博客,请务必保留此出处http://tianxingzhe.blog.51cto.com/3390077/1690814

目录
相关文章
|
7月前
|
Java
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
124 0
|
7月前
|
Java API
BigDecimal基本用法详解
BigDecimal基本用法详解
84 1
|
4月前
|
存储 Java API
"揭秘!为何BigDecimal成为精准计算的守护神?告别浮点数误差,让每一分钱都精准无误!"
【8月更文挑战第11天】在编程中处理金融或科学计算时,常遇浮点数运算精度丢失问题。Java的`double`和`float`虽能覆盖广泛数值范围,但在特定小数运算上力有未逮。`BigDecimal`则以其独特的设计确保了精度。它位于`java.math`包内,通过`BigInteger`存储数值绝对值及`scale`表示小数位数,从而精确表示任意精度的小数。
67 4
|
5月前
|
存储 Java 数据库
BigDecimal 用法总结
BigDecimal 用法总结
89 0
|
6月前
|
存储 Java API
JavaSE——常用API进阶二(2/8)-BigDecimal(BigDecimal的常见构造器、常用方法,用法示例,使用规范)
JavaSE——常用API进阶二(2/8)-BigDecimal(BigDecimal的常见构造器、常用方法,用法示例,使用规范)
56 1
|
7月前
|
存储 Java
|
7月前
|
存储 Java
35、Java 中的 Math 类、Random 随机数、UUID、格式化字符串或数字、字符串和数字的相互转换、高精度计算、BigDecimal、计算机中的浮点数都是近似值
35、Java 中的 Math 类、Random 随机数、UUID、格式化字符串或数字、字符串和数字的相互转换、高精度计算、BigDecimal、计算机中的浮点数都是近似值
104 0
BigDecimal加减乘除计算以及比较大小
BigDecimal加减乘除计算以及比较大小
211 0
BigDecimal加减乘除计算以及比较大小
|
Java API
BigDecimal常见用法详细说明
BigDecimal常见用法详细说明
149 0
|
Java API
Java使用BigDecimal(公式精确计算)+(精度丢失问题)
Java使用BigDecimal(公式精确计算)+(精度丢失问题)
393 0
Java使用BigDecimal(公式精确计算)+(精度丢失问题)