java bigdecimal的几种取舍方式 -回复
- 格式:doc
- 大小:11.72 KB
- 文档页数:4
java bigdecimal 取整进一法BigDecimal是Java中一个非常有用的工具类,用于精确处理高精度的浮点数运算。
在实际开发中,我们经常需要对浮点数进行取整操作,而取整进一法是其中一种常用的方式。
本文将围绕BigDecimal的取整进一法进行详细介绍和使用案例,同时会探讨在使用BigDecimal进行取整时需要注意的一些问题。
一、BigDecimal简介BigDecimal是Java中一个用于高精度计算的类,它能够准确表示任意大小的浮点数,并且可以保留指定的小数位数。
BigDecimal是不可变的,每次进行运算操作时都会返回一个新的BigDecimal对象,原对象不会被修改。
它支持四种取整方式:向上取整、向下取整、四舍五入、丢弃小数部分。
二、BigDecimal的取整进一法在实际的开发中,我们经常需要对浮点数进行取整操作。
取整进一法是一种常见的取整方式,即将浮点数向上取整到最接近它的整数。
对于正数来说,向上取整即是将小数舍去,保留整数部分,并加1;对于负数来说,向上取整即是将小数舍去,保留整数部分,并减1。
在使用BigDecimal进行取整操作时,可以使用setScale方法指定保留的小数位数,并使用RoundingMode.CEILING参数表示取整进一法。
三、BigDecimal取整进一法的使用示例以下是一个使用BigDecimal进行取整进一法的示例代码:```javaimport java.math.BigDecimal;import java.math.RoundingMode;public class BigDecimalRoundingUpExample {public static void main(String[] args) {BigDecimal number = new BigDecimal("3.1415926");//使用setScale方法指定保留小数位数为2,并使用RoundingMode.CEILING参数表示取整进一法BigDecimal roundedNumber = number.setScale(2, RoundingMode.CEILING);System.out.println("原始数值:" + number);System.out.println("取整结果:" + roundedNumber);}}```运行以上代码,输出结果如下:```原始数值:3.1415926取整结果:3.15```四、取整进一法的适用场景取整进一法适用于将浮点数向上取整的场景,例如:1.计算物品价格时,需要对价格进行向上取整,保证价格不低于实际成本;2.计算利息时,需要对利率进行向上取整,确保利率计算的准确性;3.对于货币的计算,由于货币最小单位通常是分,需要对计算结果进行向上取整,以避免出现金额损失。
BigDecimal⾼精度计算熟悉扩展,java除法保留⼩数问题java保留两位⼩数问题:⽅式⼀:四舍五⼊double f = 111231.5585;BigDecimal b = new BigDecimal(f);double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();保留两位⼩数---------------------------------------------------------------⽅式⼆:java.text.DecimalFormat df =new java.text.DecimalFormat("#.00");df.format(你要格式化的数字);例:new java.text.DecimalFormat("#.00").format(3.1415926)#.00 表⽰两位⼩数 #.0000四位⼩数以此类推...⽅式三:double d = 3.1415926;String result = String .format("%.2f");%.2f %. 表⽰⼩数点前任意位数 2 表⽰两位⼩数格式后的结果为f 表⽰浮点型⽅式四:NumberFormat ddf1=NumberFormat.getNumberInstance() ;void setMaximumFractionDigits(int digits)digits 显⽰的数字位数为格式化对象设定⼩数点后的显⽰的最多位,显⽰的最后位是舍⼊的import java.text.* ;import java.math.* ;class TT{public static void main(String args[]){ double x=23.5455;NumberFormat ddf1=NumberFormat.getNumberInstance() ;ddf1.setMaximumFractionDigits(2);String s= ddf1.format(x) ;System.out.print(s);}}---------------------------------------------------------------------------------------------------------有⼀篇:(1)、浮点数精确计算胜利油⽥三流合⼀项⽬中⼀直存在⼀个问题,就是每次报表统计的物资⾦额和实际的⾦额要差那么⼏分钱,和实际⾦额不⼀致,让客户觉得总是不那么舒服,原因是因为我们使⽤java的浮点类型double来定义物资⾦额,并且在报表统计中我们经常要进⾏⼀些运算,但Java中浮点数(double、float)的计算是⾮精确计算,请看下⾯⼀个例⼦: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.0600000000000000050.5800000000000001401.499999999999941.2329999999999999这个问题就⾮常严重了,如果你有123.3元要购买商品,⽽计算机却认为你只有123.29999999999999元,钱不够,计算机拒绝交易。
Java中的BigDecimal类提供了一系列方法来执行数字运算。
这些方法可以归为以下四类:加法、减法、乘法和除法。
1.加法方法:add(BigDecimal value):将指定的值加到此BigDecimal。
add(BigDecimal augend, MathContext mc):使用指定的上下文将此BigDecimal与另一个相加。
plus():返回此BigDecimal的正数值。
plus(MathContext mc):使用指定的上下文返回此BigDecimal的正数值。
2.减法方法:subtract(BigDecimal value):从此BigDecimal中减去指定的值。
subtract(BigDecimal subtrahend, MathContext mc):使用指定的上下文从此BigDecimal中减去另一个BigDecimal。
negate():返回此BigDecimal的负数值。
negate(MathContext mc):使用指定的上下文返回此BigDecimal的负数值。
3.乘法方法:multiply(BigDecimal value):将此BigDecimal乘以指定的值。
multiply(BigDecimal multiplicand, MathContext mc):使用指定的上下文将此BigDecimal乘以另一个BigDecimal。
pow(int n):返回此BigDecimal的n次幂。
pow(int n, MathContext mc):使用指定的上下文返回此BigDecimal的n次幂。
4.除法方法:divide(BigDecimal divisor):将此BigDecimal除以指定的值。
divide(BigDecimal divisor, MathContext mc):使用指定的上下文将此BigDecimal除以另一个BigDecimal。
JAVABigDecimal详解加减乘除⼩数舍⼊模式 java.math.BigDecimal概述Java在java.math包中提供的API类BigDecimal,⽤来对超过16位有效位的数进⾏精确的运算。
双精度浮点型变量double可以处理16位有效数,但在实际应⽤中,可能需要对更⼤或者更⼩的数进⾏运算和处理。
⼀般情况下,对于那些不需要准确计算精度的数字,我们可以直接使⽤Float和Double 处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。
所以开发中.如果我们需要精确计算的结果,则必须使⽤BigDecimal类来操作。
B igDecimal所创建的是对象,故我们不能使⽤传统的+、-、*、/ 等算术运算符直接对其对象进⾏数学运算,⽽必须调⽤其相对应的⽅法。
⽅法中的参数也必须是BigDecimal的对象。
构造器是类的特殊⽅法,专门⽤来创建对象,特别是带有参数的对象。
BigDecimal常⽤构造函数1. BigDecimal(int)创建⼀个具有参数所指定整数值的对象2. BigDecimal(double)创建⼀个具有参数所指定双精度值的对象3. BigDecimal(long)创建⼀个具有参数所指定长整数值的对象4. BigDecimal(String) 常⽤创建⼀个具有参数所指定以字符串表⽰的数值的对象使⽤⽰例:BigDecimal a =new BigDecimal(0.1);System.out.println("a values is:"+a);System.out.println("=====================");BigDecimal b =new BigDecimal("0.1");System.out.println("b values is:"+b);结果⽰例:a values is:0.1000000000000000055511151231257827021181583404541015625=====================b values is:0.1原因分析:1)参数类型为double的构造⽅法的结果有⼀定的不可预知性。
Java中的BigDecimal类是用于高精度计算的类,它可以精确表示任意精度的十进制数。
在实际应用中,经常需要对BigDecimal进行取整操作,这篇文章将介绍如何使用进一法对BigDecimal进行取整操作。
1. BigDecimal类简介BigDecimal类位于java.math包中,它提供了高精度的十进制运算。
和基本数据类型(如double和float)相比,BigDecimal可以精确表示小数,并且不会出现舍入误差。
在财务计算和科学计算中,使用BigDecimal可以得到准确的结果。
2. BigDecimal的取整方法在Java中,对BigDecimal进行取整操作可以使用setScale方法。
setScale方法有两个参数,第一个参数是保留小数点后的位数,第二个参数是取整的模式。
3. 取整的模式在BigDecimal类中,取整的模式有四种:- BigDecimal.ROUND_UP:向远离零的方向取整,即正数向正无穷大取整,负数向负无穷大取整。
- BigDecimal.ROUND_DOWN:向靠近零的方向取整,即正数向零取整,负数向零取整。
- BigDecimal.ROUND_HALF_UP:四舍五入,当小数部分大于0.5时向远离零的方向取整。
- BigDecimal.ROUND_HALF_DOWN:四舍五入,当小数部分大于或等于0.5时向远离零的方向取整。
4. 进一法取整进一法是取整的一种常见方法,它指的是将小数部分大于0的数向正无穷大方向取整,将小数部分小于等于0的数向零方向取整。
在Java 中,可以使用ROUND_UP模式来实现进一法取整。
5. 示例代码下面是一个使用进一法对BigDecimal进行取整的示例代码:```javaimport java.math.BigDecimal;public class M本人n {public static void m本人n(String[] args) {BigDecimal num1 = new BigDecimal("3.14");BigDecimal num2 = new BigDecimal("-3.14");System.out.println(num1.setScale(0,BigDecimal.ROUND_UP)); // 输出3System.out.println(num2.setScale(0,BigDecimal.ROUND_UP)); // 输出-3}}```在示例代码中,先创建了两个BigDecimal对象num1和num2,分别表示3.14和-3.14。
详解java中BigDecimal精度问题⽬录⼀、背景⼆、BigDecimal构造函数1、四种构造函数2、为什么会出现这种情况3、如何解决三、常⽤⽅法1、常⽤⽅法2、取舍规则四、格式化⼀、背景在实际开发中,对于不需要任何准确计算精度的属性可以直接使⽤float或double,但是如果需要精确计算结果,则必须使⽤BigDecimal,例如价格、质量。
为什么这么说,主要有两点1、double计算会有精度丢失问题2、在除法运算时,BigDecimal提供了丰富的取舍规则。
(double虽然可以通过NumberFormat进⾏四舍五⼊,但是NumberFormat是线程不安全的)对于精度问题我们可以看下实际的例⼦public static void main(String[] args) {//正常 3.3System.out.println("加法结果:"+(1.1+2.2));//正常 -7.9System.out.println("减法结果:"+(2.2-10.1));//正常 2.42System.out.println("乘法结果:"+(1.1*2.2));//正常 0.44System.out.println("除法结果:"+(4.4/10));}实际控制台输出为什么会这样在于我们的计算机是⼆进制的。
浮点数没有办法是⽤⼆进制进⾏精确表⽰。
我们的CPU表⽰浮点数由两个部分组成:指数和尾数,这样的表⽰⽅法⼀般都会失去⼀定的精确度,有些浮点数运算也会产⽣⼀定的误差。
如:2.4的⼆进制表⽰并⾮就是精确的2.4。
反⽽最为接近的⼆进制表⽰是2.3999999999999999。
浮点数的值实际上是由⼀个特定的数学公式计算得到的。
⼆、BigDecimal构造函数1、四种构造函数BigDecimal(int) //创建⼀个具有参数所指定整数值的对象。
1 ROUND_UP 舍⼊远离零的舍⼊模式。
在丢弃⾮零部分之前始终增加数字(始终对⾮零舍弃部分前⾯的数字加1)。
注意,此舍⼊模式始终不会减少计算值的⼤⼩。
2ROUND_DOWN 接近零的舍⼊模式。
在丢弃某部分之前始终不增加数字(从不对舍弃部分前⾯的数字加1,即截短)。
注意,此舍⼊模式始终不会增加计算值的⼤⼩。
3ROUND_CEILING 接近正⽆穷⼤的舍⼊模式。
如果 BigDecimal 为正,则舍⼊⾏为与 ROUND_UP 相同;如果为负,则舍⼊⾏为与 ROUND_DOWN 相同。
注意,此舍⼊模式始终不会减少计算值。
4ROUND_FLOOR 接近负⽆穷⼤的舍⼊模式。
如果 BigDecimal 为正,则舍⼊⾏为与 ROUND_DOWN 相同;如果为负,则舍⼊⾏为与 ROUND_UP 相同。
注意,此舍⼊模式始终不会增加计算值。
5ROUND_HALF_UP 向“最接近的”数字舍⼊,如果与两个相邻数字的距离相等,则为向上舍⼊的舍⼊模式。
如果舍弃部分 >= 0.5,则舍⼊⾏为与 ROUND_UP 相同;否则舍⼊⾏为与 ROUND_DOWN 相同。
注意,这是我们⼤多数⼈在⼩学时就学过的舍⼊模式(四舍五⼊)。
6ROUND_HALF_DOWN向“最接近的”数字舍⼊,如果与两个相邻数字的距离相等,则为上舍⼊的舍⼊模式。
如果舍弃部分 > 0.5,则舍⼊⾏为与 ROUND_UP 相同;否则舍⼊⾏为与 ROUND_DOWN 相同(五舍六⼊)。
7ROUND_HALF_EVEN 向“最接近的”数字舍⼊,如果与两个相邻数字的距离相等,则向相邻的偶数舍⼊。
如果舍弃部分左边的数字为奇数,则舍⼊⾏为与 ROUND_HALF_UP 相同;如果为偶数,则舍⼊⾏为与 ROUND_HALF_DOWN 相同。
注意,在重复进⾏⼀系列计算时,此舍⼊模式可以将累加错误减到最⼩。
此舍⼊模式也称为“银⾏家舍⼊法”,主要在美国使⽤。
import java.math.BigDecimal;public class Arith {/*** 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精确的浮点数运算,包括加减乘除和四舍五入。
*/// 默认除法运算精度private static final int DEF_DIV_SCALE = 10;// 这个类不能实例化private Arith() {}/*** 提供精确的加法运算。
** @param v1* 被加数* @param v2* 加数* @return 两个参数的和*/public static double add(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue();}/*** 提供精确的减法运算。
** @param v1* 被减数* @param v2* 减数* @return 两个参数的差*/public static double sub(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue();}/*** 提供精确的乘法运算。
** @param v1* 被乘数* @param v2* 乘数* @return 两个参数的积*/public static double mul(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2));return b1.multiply(b2).doubleValue();}/*** 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到小数点以后10位,以后的数字四舍五入。
Java中BigDecimal的加减乘除、⽐较⼤⼩与使⽤注意事项前⾔⼀、BigDecimal 的加减乘除BigDecimal bignum1 = new BigDecimal("10");BigDecimal bignum2 = new BigDecimal("5");BigDecimal bignum3 = null;//加法bignum3 = bignum1.add(bignum2);System.out.println("和是:" + bignum3);//减法bignum3 = bignum1.subtract(bignum2);System.out.println("差是:" + bignum3);//乘法bignum3 = bignum1.multiply(bignum2);System.out.println("积是:" + bignum3);//除法bignum3 = bignum1.divide(bignum2);System.out.println("商是:" + bignum3);运⾏结果为:⼆、BigDecimal 的⽐较⼤⼩。
BigDecimal num1 = new BigDecimal("0");BigDecimal num2 = new BigDecimal("1");BigDecimal num3 = new BigDecimal("2");BigDecimal num = new BigDecimal("1"); //⽤做⽐较的值System.out.println(pareTo(num)); //⼩于时,返回 -1System.out.println(pareTo(num)); //等于时,返回 0System.out.println(pareTo(num)); //⼤于时,返回 1这是输出结果:解释下注释⾥⾯了。
浅谈java中BigDecimal的equals与compareTo的区别这两天在处理⽀付⾦额校验的时候出现了点问题,有个⾦额⽐较我⽤了BigDecimal的equals⽅法来⽐较两个⾦额是否相等,结果导致⾦额⽐较出现错误(⽐如3.0与3.00的⽐较等)。
【注:以下所讲都是以sun jdk 1.4.2版本为例,其他版本实现未必⼀致,请忽略】⾸先看⼀下BigDecimal的equals⽅法:public boolean equals(Object x){if (!(x instanceof BigDecimal))return false;BigDecimal xDec = (BigDecimal) x;return scale == xDec.scale && intVal.equals(xDec.intVal);}可以看到BigDecimal的euquals⽅法是先判断要⽐较的数据类型,如果对象类型⼀致前提下同时判断精确度(scale)和值(BigInteger的equals⽅法)是否⼀致。
其实javadoc⾥⾯就已经写的很明⽩:“Compares this BigDecimal with the specified Object for equality. Unlike compareTo, this method considers two 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).”只是⾃⼰没有去注意罢了!再看⼀下compareTo⽅法:public int compareTo(BigDecimal val){/* Optimization: would run fine without the next three lines */int sigDiff = signum() - val.signum();if (sigDiff != 0)return (sigDiff > 0 ? 1 : -1);/* If signs match, scale and compare intVals */BigDecimal arg[] = new BigDecimal[2];arg[0] = this; arg[1] = val;matchScale(arg);return arg[0]pareTo(arg[1].intVal);}可以看到这个⽅法⾥⾯有个matchScale的处理,意思是把精确度低的那个对象转换为⾼精确度,然后再进⾏⽐较(同样是BigInteger的compareTo⽅法),matchScale的实现如下:private static void matchScale(BigDecimal[] val) {if (val[0].scale < val[1].scale)val[0] = val[0].setScale(val[1].scale);else if (val[1].scale < val[0].scale)val[1] = val[1].setScale(val[0].scale);}做个简单测试:System.out.println(new BigDecimal("1.2").equals(new BigDecimal("1.20"))); //输出falseSystem.out.println(new BigDecimal("1.2").compareTo(new BigDecimal("1.20")) == 0); //输出true另外注意到我上⾯BigDecimal的构造⽅法⾥⾯传⼊的都是字符串,如果传⼊的是数字类型的话会有什么结果,⼤家可以⾃⼰测试⼀下,然后分析⼀下原因:System.out.println(new BigDecimal("1.2").equals(new BigDecimal("1.20"))); //输出falseSystem.out.println(new BigDecimal("1.2").compareTo(new BigDecimal("1.20")) == 0); //输出trueSystem.out.println(new BigDecimal(1.2).equals(new BigDecimal("1.20"))); //输出是?System.out.println(new BigDecimal(1.2).compareTo(new BigDecimal("1.20")) == 0); //输出是?System.out.println(new BigDecimal(1.2).equals(new BigDecimal(1.20))); //输出是?System.out.println(new BigDecimal(1.2).compareTo(new BigDecimal(1.20)) == 0);//输出是?最后结论是:对于BigDecimal的⼤⼩⽐较,⽤equals⽅法的话会不仅会⽐较值的⼤⼩,还会⽐较两个对象的精确度,⽽compareTo⽅法则不会⽐较精确度,只⽐较数值的⼤⼩。
java bigdecimal的几种取舍方式-回复
Java中的BigDecimal类提供了对高精度浮点数进行计算和取舍的功能。
在实际应用中,我们经常会遇到需要对浮点数进行精确计算和取舍的情况。
本文将介绍Java BigDecimal类的几种取舍方式,包括舍入模式、精度设置、取整方式和截断方式。
1. 舍入模式(Rounding Mode)
舍入模式是指在进行舍入计算时,按照一定的规则决定最终的取舍结果。
BigDecimal类提供了8种不同的舍入模式,分别是:
- ROUND_UP:向远离零的方向舍入,即向正无穷大方向舍入。
例如,2.1会舍入为3。
- ROUND_DOWN:向接近零的方向舍入。
例如,2.9会舍入为2。
- ROUND_CEILING:向正无穷大的方向舍入。
例如,2.1会舍入为3,-2.1会舍入为-2。
- ROUND_FLOOR:向负无穷大的方向舍入。
例如,2.1会舍入为2,-2.1会舍入为-3。
- ROUND_HALF_UP:向最接近的整数舍入,其中0.5舍入到正无穷大方向。
例如,2.5会舍入为3,2.4会舍入为2。
- ROUND_HALF_DOWN:向最接近的整数舍入,其中0.5舍入到零的方向。
例如,2.5会舍入为2,2.6会舍入为3。
- ROUND_HALF_EVEN:如果舍入位左边的数字是奇数,则采用ROUND_HALF_UP;如果是偶数,则采用ROUND_HALF_DOWN。
例如,
2.5会舍入为2,
3.5会舍入为4。
- ROUND_UNNECESSARY:计算结果精确地舍入,不需要舍入模式。
如果要进行的操作所得到的精度不符合规范,则抛出ArithmeticException。
舍入模式可通过调用BigDecimal的setScale方法来设置,例如:
BigDecimal result = value.setScale(2, RoundingMode.DOWN);
2. 精度设置
精度设置是指限定结果的小数位数。
BigDecimal类提供了setScale方法来设置结果的小数位数和舍入模式。
例如:
BigDecimal result = value.setScale(2, RoundingMode.HALF_UP);
上述代码将结果的小数位数设置为2位,并使用ROUND_HALF_UP舍入模式。
3. 取整方式
除了进行小数位舍入,还可以对结果进行取整操作。
BigDecimal类提供了几种取整方式:
- toBigInteger:将BigDecimal对象转换为BigInteger类型。
例如:
BigDecimal value = new BigDecimal("2.5");
BigInteger integerValue = value.toBigInteger();
上述代码将2.5转换为2。
- intValueExact:将BigDecimal对象转换为int类型。
如果转换结果超出int的范围,则会抛出ArithmeticException异常。
- longValueExact:将BigDecimal对象转换为long类型。
如果转换结果超出long的范围,则会抛出ArithmeticException异常。
4. 截断方式
截断方式是指将结果截断到指定的小数位数。
BigDecimal类提供了setScale方法来设置结果的小数位数,但它会根据舍入模式进行舍入操作。
如果想要简单地截断小数位数,可以使用stripTrailingZeros方法。
例如:
BigDecimal result = value.stripTrailingZeros();
上述代码将结果中末尾的零去除掉,获得一个截断的BigDecimal对象。
在实际应用中,我们需要根据具体需求选择合适的取舍方式。
如果要进行精确计算,应该使用适当的舍入模式;如果只是为了显示结果,可以使用
截断方式。
同样重要的是,要注意输入数据的精度和范围,以避免出现溢出或精度丢失的问题。
综上所述,Java BigDecimal类提供了几种取舍方式,包括舍入模式、精度设置、取整方式和截断方式。
根据具体需求选择合适的方法,可以实现对高精度浮点数的精确计算和取舍操作。
这为开发人员在处理涉及金融、科学计算等领域的数据时提供了便利。