bigdecimal.divide,bigdecimaldivide方法不四舍五入

http://www.itjxue.com  2023-01-16 00:34  来源:未知  点击次数: 

关于BigDecimal.divide()的精度问题

网上随便一搜,是这么写的:

ROUND_CEILING

Rounding mode to round towards positive infinity.

向正无穷方向舍入

ROUND_DOWN

Rounding mode to round towards zero.

向零方向舍入

ROUND_FLOOR

Rounding mode to round towards negative infinity.

向负无穷方向舍入

ROUND_HALF_DOWN

Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.

向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5

ROUND_HALF_EVEN

Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.

向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP ,如果是偶数,使用ROUND_HALF_DOWN

ROUND_HALF_UP

Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.

向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6

ROUND_UNNECESSARY

Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary.

计算结果是精确的,不需要舍入模式

ROUND_UP

Rounding mode to round away from zero.

向远离0的方向舍入

MathContext mathContext = new MathContext(2,RoundingMode.UP);

BigDecimal test1 = BigDecimal.valueOf(19785.076);

BigDecimal test2 = BigDecimal.valueOf(100.0d);

LogUtil.i("result="+test1.divide(test2,mathContext).doubleValue());

结果是多少?

200.0

奇怪了,为什么是200.0?其实我的目的是想结果为:197.86。因为我是这么想的:保留2位小数,然后小数的2位之后如果还有数(也就是说后面的大于0),那么会进1位。

但结果就是200.0,后来查了一下那MathContext里面的2并不是指保留2位小数,而是指的有效位数。所以BigDecimal.divide(BigDecimical,MathContext)就不能用了。直接用BigDecimal.divide(BigDecimaldivisor,RoundingModeroundingMode).setScale(intnewScale,RoundingModeroundingMode)来解决问题。

但是,直接用BigDecimal.divide(BigDecimaldivisor,RoundingModeroundingMode)那么它是保留几位呢?懒得看源码,简单测试了一下,结果是:

eg1:

BigDecimal test1 = BigDecimal.valueOf(19785.076);

BigDecimal test2 = BigDecimal.valueOf(100.0d);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.851

eg2:

BigDecimal test1 = BigDecimal.valueOf(19785.070);

BigDecimal test2 = BigDecimal.valueOf(100.0d);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.86

eg3:

BigDecimal test1 = BigDecimal.valueOf(19785.006);

BigDecimal test2 = BigDecimal.valueOf(100.0d);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.851

eg4:

BigDecimal test1 = BigDecimal.valueOf(19785.06);

BigDecimal test2 = BigDecimal.valueOf(100.0d);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.86

eg5:

BigDecimal test1 = BigDecimal.valueOf(19785.1);

BigDecimal test2 = BigDecimal.valueOf(100.0d);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.9

eg6:

BigDecimal test1 = BigDecimal.valueOf(19785);

BigDecimal test2 = BigDecimal.valueOf(100.0d);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:198.0

eg7:

BigDecimal test1 = BigDecimal.valueOf(19785);

BigDecimal test2 = BigDecimal.valueOf(100);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:198.0

eg8:

BigDecimal test1 = BigDecimal.valueOf(19785);

BigDecimal test2 = BigDecimal.valueOf(100.01);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:198.0

eg9:

BigDecimal test1 = BigDecimal.valueOf(19785);

BigDecimal test2 = BigDecimal.valueOf(100.11);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:198.0

eg10:

BigDecimal test1 = BigDecimal.valueOf(19785);

BigDecimal test2 = BigDecimal.valueOf(100.91);

LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.0

发现规律了吗?

RoundingMode:

1、除数的小数点位数与结果的位数直接相关联,而被除数的小数点位数与结果的位数没有啥关系(至少简单测试一下看上去是这样),但是被除数的小数位数不是说没有用,而是对结果与直接关联。

2、除数如果是N位小数,那么结果就会是N位小数。但有2个例外:

①除数如果没有小数,在BigDecimal后面再继续用doubleValue会发现有xxx.0出现;

②除数的最后1位如果为0,那么就会被忽略。如上eg2与eg3。

先不写了。反正就没打算给别人看的,自己记录一下就OK了,所以也没啥排版,知识也不够全面。

BigDecimal使用详解

一、构造方法

BigDecimal的构造方法有很多种,大家最常用的如下方式:

BigDecimal bd1=new BigDecimal(10);

BigDecimal bd2=new BigDecimal("10");

二、四则预算

加法:bigDecimal1.add(bigDecimal2);

减法:bigDecimal1.subtract(bigDecimal2);

乘法:bigDecimal1.multiply(bigDecimal2);

除法:bigDecimal1.divide(bigDecimal2);

三、对小数的处理

(1).DecimalFormat类

例:

DecimalFormat df =new DecimalFormat("#.00");

df.format(3.1415926);

结果输出3.14

(2)setScale方法

double f = 111231.5585;

BigDecimal b = new BigDecimal(f);

double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); //保留2位小数

四、比较大小

BigDecimal比较大小不能使用equals因为不仅比较值还比较精度

这里使用BigDecimal自带方法compareTo

例:

BigDecimal a = new BigDecimal("1.00");

BigDecmial b = new BigDecimal(1);

a.compareTo(b)==0结果是true

这里返回值含义: -1小于 0等于 1大于

关于BigDecimal的divide()方法。。。求解。。。。。。。。。。。。。。。。。

BigDecimal的除法,需要指定计算答案的精度,那样肯定会报异常。

MathContext mc = new MathContext(2, RoundingMode.HALF_DOWN);

BigDecimal a = new BigDecimal(0.5);

BigDecimal bd1 = new;

BigDecimal("30000000000000000000000000000000000000000000000000000000000");

BigDecimal bd2 = new BigDecimal(3);

//MathContext,第一个参数表示你要保留几位小数,第二参数表示最后一位是取顶。

构造方法

BigDecimal一共有4个构造方法:

BigDecimal(int) 创建一个具有参数所指定整数值的对象。

BigDecimal(double) 创建一个具有参数所指定双精度值的对象。(不建议采用)

BigDecimal(long) 创建一个具有参数所指定长整数值的对象。

BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。

java将一个数按照规定拆分成几个数的和?

除以7必然涉及到保留两位小数的四舍五入问题,这里使用java的BigDecimal来处理除法,四舍五入的保留方法使用RoundingMode.HALF_EVEN:

RoundingMode.CEILING:取右边最近的整数

RoundingMode.DOWN:去掉小数部分取整,也就是正数取左边,负数取右边,相当于向原点靠近的方向取整

RoundingMode.FLOOR:取左边最近的正数

RoundingMode.HALF_DOWN:五舍六入,负数先取绝对值再五舍六入再负数

RoundingMode.HALF_UP:四舍五入,负数原理同上

RoundingMode.HALF_EVEN:这个比较绕,整数位若是奇数则四舍五入,若是偶数则五舍六入

我认为无论如何都是无法避免四舍五入导致的精度变化的问题,解决方法只能在最后的结果强行再舍掉小数位数:

public class Main {

public static void main(String[] args) {

BigDecimal bigDecimal = new BigDecimal("10");

BigDecimal seven = new BigDecimal("7");

BigDecimal b1 = bigDecimal.divide(seven, 2, RoundingMode.HALF_EVEN).multiply(new BigDecimal("2"));

System.out.println(b1);

BigDecimal b2 = bigDecimal.divide(seven, 2, RoundingMode.HALF_EVEN);

System.out.println(b2);

BigDecimal b3 = bigDecimal.divide(seven, 2, RoundingMode.HALF_EVEN).multiply(new BigDecimal("2"));

System.out.println(b3);

BigDecimal b4 = bigDecimal.divide(seven, 2, RoundingMode.HALF_EVEN);

System.out.println(b4);

BigDecimal b5 = bigDecimal.divide(seven, 2, RoundingMode.HALF_EVEN);

System.out.println(b5);

System.out.println(b1.add(b2).add(b3).add(b4).add(b5).setScale(0,RoundingMode.HALF_EVEN));

}

}

运行结果:

bigdecimal加减乘除有哪些?

//BigDecimal add = ma.add(mb),System.out.println("加法:"+add)。BigDecimal sub =ma.subtract(mb),System.out.println("减法:"+sub)。

使用BigDecimal要用String来够造,要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。

需要注意的是除法运算divide:

BigDecimal除法可能出现不能整除的情况,比如 4.5/1.3,这时会报错java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result。

其实divide方法有可以传三个参数:public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 第一参数表示除数, 第二个参数表示小数点后保留位数,第三个参数表示舍入模式,只有在作除法运算或四舍五入时才用到舍入模式。

Java里面BigDecimal.divide()方法能不能实现保留小数点前后共35位这样的操作

没有这样的方法,你自己封装一个就行了啊,把结果转成35位就行了

(责任编辑:IT教学网)

更多

相关网站优化文章