java中BigDecimal详解
⾸先,学习⼀个东西,我们都必须要带着问题去学,这边我分为 【为什么?】【是什么?】【怎么⽤?】
【为什么要⽤BigDecimal?】
⾸先,我们先看⼀下,下⾯这个现象
那为什么会出现这种情况呢?
因为不论是float 还是double都是浮点数,⽽计算机是⼆进制的,浮点数会失去⼀定的精确度。
注:根本原因是:⼗进制值通常没有完全相同的⼆进制表⽰形式;⼗进制数的⼆进制表⽰形式可能不精确。只能⽆限接近于那个值
但是,在项⽬中,我们不可能让这种情况出现,特别是⾦融项⽬,因为涉及⾦额的计算都必须⼗分精确,你想想,如果你的⽀付宝账户余额显⽰193.99999999999998,那是⼀种怎么样的体验?
【BigDecimal是什么?】
1、简介
Java在java.math包中提供的API类BigDecimal,⽤来对超过16位有效位的数进⾏精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应⽤中,需要对更⼤或者更⼩的数进⾏运算和处理。float和double只能⽤来做科学计算或者是⼯程计算,在商业计算中要⽤java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使⽤传统的+、-、*、/等算术运算符直接对其对象进⾏数学运算,⽽必须调⽤其相对应的⽅法。⽅法中的参数也必须是BigDecimal的对象。构造器是类的特殊⽅法,专门⽤来创建对象,特别是带有参数的对象。
2、构造器描述
BigDecimal(int) 创建⼀个具有参数所指定整数值的对象。
BigDecimal(double) 创建⼀个具有参数所指定双精度值的对象。 //不推荐使⽤
bigdecimal除法保留小数BigDecimal(long) 创建⼀个具有参数所指定长整数值的对象。
BigDecimal(String) 创建⼀个具有参数所指定以字符串表⽰的数值的对象。//推荐使⽤
3、⽅法描述
add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
toString() 将BigDecimal对象的数值转换成字符串。
doubleValue() 将BigDecimal对象中的值以双精度数返回。
floatValue() 将BigDecimal对象中的值以单精度数返回。
longValue() 将BigDecimal对象中的值以长整数返回。
intValue() 将BigDecimal对象中的值以整数返回。
特别说明⼀下,为什么BigDecimal(double) 不推荐使⽤,
看上⾯代码运⾏结果,你就应该知道为什么不推荐使⽤了,因为⽤这种⽅式也会导致计算有问题,
为什么会出现这种情况呢?
JDK的描述:1、参数类型为double的构造⽅法的结果有⼀定的不可预知性。有⼈可能认为在Java中写⼊newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(⾮标度值 1,其标度为 1),但是它实际上等于
0.1000000000000000055511151231257827021181583404541015625。这是因为0.1⽆法准确地表⽰为 double(或者说对于该情况,不能表⽰为任何有限长度的⼆进制⼩数)。这样,传⼊到构造⽅法的值不会正好等于 0.1(虽然表⾯上等于该值)。
2、另⼀⽅⾯,String 构造⽅法是完全可预知的:写⼊ newBigDecimal("0.1") 将创建⼀个 BigDecimal,它正好等于预期的 0.1。因此,⽐较⽽⾔,通常建议优先使⽤String构造⽅法
当double必须⽤作BigDecimal的源时,请使⽤String(double)转成String,然后使⽤String构造⽅法,或使⽤BigDecimal的静态⽅法valueOf,如下
【怎么⽤?】
这边我就不多说什么了,直接上代码,都挺简单的,最基本的加减乘除,应该能看的懂
这边特别提⼀下,如果进⾏除法运算的时候,结果不能整除,有余数,这个时候会报java.lang.ArithmeticException:
,这边我们要避免这个错误产⽣,在进⾏除法运算的时候,针对可能出现的⼩数产⽣的计算,必须要
多传两个参数
divide(BigDecimal,保留⼩数点后⼏位⼩数,舍⼊模式)
舍⼊模式
ROUND_CEILING //向正⽆穷⽅向舍⼊
ROUND_DOWN //向零⽅向舍⼊
ROUND_FLOOR //向负⽆穷⽅向舍⼊
ROUND_HALF_DOWN //向(距离)最近的⼀边舍⼊,除⾮两边(的距离)是相等,如果是这样,向下舍⼊, 例如1.55 保留⼀位⼩数结果为1.5
ROUND_HALF_EVEN //向(距离)最近的⼀边舍⼊,除⾮两边(的距离)是相等,如果是这样,如果保留位数是奇数,使⽤ROUND_HALF_UP,如果是偶数,使⽤ROUND_HALF_DOWN
ROUND_HALF_UP //向(距离)最近的⼀边舍⼊,除⾮两边(的距离)是相等,如果是这样,向上舍⼊, 1.55保留⼀位⼩数结果为1.6,也就是我们常说的“四舍五⼊”
ROUND_UNNECESSARY //计算结果是精确的,不需要舍⼊模式
ROUND_UP //向远离0的⽅向舍⼊
需要对BigDecimal进⾏截断和四舍五⼊可⽤setScale⽅法,例:
参考博客连接:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论