java BigDecimal.ROUND_UP和BigDecimal.ROUND_DOWN的用处
今天在工作中遇到了这样的一个需求,
一个小数,例如1.7777777,或者1.3333333,不管后面的位数是多少,只保留到小数点后第二位,但是不是四舍五入,1.7777777处理后就是1.77,1.3333333处理后就是1.33
这个就要用到BigDecimal#setScale的方法了。
具体看如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import java.math.BigDecimal; import java.math.RoundingMode; public class ScaleTest { public static void main(String[] args) { double a = 1.66728D; double b = 1.33333D; double c = 1.00000D; BigDecimal aa = new BigDecimal(a); BigDecimal bb = new BigDecimal(b); BigDecimal cc = new BigDecimal(c); System.out.println(aa.setScale(2, BigDecimal.ROUND_UP)); System.out.println(aa.setScale(2, BigDecimal.ROUND_DOWN)); System.out.println(bb.setScale(2, BigDecimal.ROUND_UP)); System.out.println(bb.setScale(2, BigDecimal.ROUND_DOWN)); System.out.println(cc.setScale(2, BigDecimal.ROUND_UP)); System.out.println(cc.setScale(2, BigDecimal.ROUND_DOWN)); System.out.println("-------------------------------------"); System.out.println(aa.setScale(2, RoundingMode.UP)); System.out.println(aa.setScale(2, RoundingMode.DOWN)); System.out.println(bb.setScale(2, RoundingMode.UP)); System.out.println(bb.setScale(2, RoundingMode.DOWN)); System.out.println(cc.setScale(2, RoundingMode.UP)); System.out.println(cc.setScale(2, RoundingMode.DOWN)); } } |
输出结果如下:
1.67
1.66
1.34
1.33
1.00
1.00
————————————-
1.67
1.66
1.34
1.33
1.00
1.00
上面仅仅是根据我的需要举了BigDecimal.ROUND_UP和BigDecimal.ROUND_DOWN的例子,下面就用个表格来分析下。
ROUND_UP ROUND_DOWN
1.66728D 1.67 1.66
1.33333D 1.34 1.33
1.00000D 1.00 1.00
也就是说,ROUND_DOWN,是一个舍位取值的概念,我保留了两位小数,我不管你后面的小数值如何,也不会四舍五入,就硬生生的给阶段,相当于什么呢,就是我从小数点后面开始取两位,两位后面的都不要了,相当于一个截取字符串的操作。
而ROUND_UP那,很宽容,很大方,我不管你第三位的小数是多少,我都给你加一最小单位(比如保留两位小数,最小单位是0.01,保留三位小数,最小单位就是0.001),当然了,你保留到最后一位的数字如果是0的话,那么就不加了。
而这两个作用在咱们实际当中什么情况下不能使用四舍五入,需要用这两个呢?
用个应用题举例子吧,
一个篮子可以装10个苹果,现在有82个苹果,需要几个篮子来装?
9个,对,这是咱们的什么结果,不正是ROUND_UP的么(只不过这道题是取小数点后0位,也就是取整的区别而已),也就很好解释为什么最小单位是0不需要再加一个最小单位了,如果我只有80个苹果,8个篮子正好装下,就不需要第九个了。
那么什么时候儿需要使用ROUND_DOWN呢,再来看下面一个例子,
每个加油站相距8公里,一公里需要耗一个油,我现在车里还有90个油,请问,我最晚在第几个加油站必须得加油了?
11个,第十一个,就是在车使用88个油到达第11个加油站后需要加油,因为我还剩2个由已经撑不到第12个加油站了。这种情况,ROUND_DOWN就派上用场了。
其实,BigDecimal不光有ROUND_UP,ROUND_DOWN,还有其他的很多值,比如:ROUND_CEILING、ROUND_HALF_DOWN等等,具体的效果可以自己实验下。
这里给出篇文章地址供参考:
http://stephen830.javaeye.com/blog/260776 JAVA对double或者float的浮点数精度计算控制方法
原文如下:
JAVA对double或者float的浮点数精度计算控制方法
文章分类:Java编程关键字: java double或者float的浮点数精度
★★★ 本篇为原创,需要引用转载的朋友请注明:《 http://stephen830.javaeye.com/blog/260776 》 谢谢支持!★★★本篇介绍了在JAVA中如何对double或者float的浮点数进行精度计算,在JAVA中提供了多种参数来实现精度的不同控制方式。具体例子如下:
Java代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | import java.math.BigDecimal; /** * 与小数位精度(四舍五入等)相关的一些常用工具方法. * * float/double的精度取值方式分为以下几种: <br> * java.math.BigDecimal.ROUND_UP <br> * java.math.BigDecimal.ROUND_DOWN <br> * java.math.BigDecimal.ROUND_CEILING <br> * java.math.BigDecimal.ROUND_FLOOR <br> * java.math.BigDecimal.ROUND_HALF_UP<br> * java.math.BigDecimal.ROUND_HALF_DOWN <br> * java.math.BigDecimal.ROUND_HALF_EVEN <br> * * @author stephen * @version 1.0.0 */ public final class RoundTool { /** * 对double数据进行取精度. * <p> * For example: <br> * double value = 100.345678; <br> * double ret = round(value,4,BigDecimal.ROUND_HALF_UP); <br> * ret为100.3457 <br> * * @param value * double数据. * @param scale * 精度位数(保留的小数位数). * @param roundingMode * 精度取值方式. * @return 精度计算后的数据. */ public static double round(double value, int scale, int roundingMode) { BigDecimal bd = new BigDecimal(value); bd = bd.setScale(scale, roundingMode); double d = bd.doubleValue(); bd = null; return d; } /** * 测试用的main方法. * * @param argc * 运行参数. */ public static void main(String[] argc) { //下面都以保留2位小数为例 //ROUND_UP //只要第2位后面存在大于0的小数,则第2位就+1 System.out.println(round(12.3401,2,BigDecimal.ROUND_UP));//12.35 System.out.println(round(-12.3401,2,BigDecimal.ROUND_UP));//-12.35 //ROUND_DOWN //与ROUND_UP相反 //直接舍弃第2位后面的所有小数 System.out.println(round(12.349,2,BigDecimal.ROUND_DOWN));//12.34 System.out.println(round(-12.349,2,BigDecimal.ROUND_DOWN));//-12.34 //ROUND_CEILING //如果数字>0 则和ROUND_UP作用一样 //如果数字<0 则和ROUND_DOWN作用一样 System.out.println(round(12.3401,2,BigDecimal.ROUND_CEILING));//12.35 System.out.println(round(-12.349,2,BigDecimal.ROUND_CEILING));//-12.34 //ROUND_FLOOR //如果数字>0 则和ROUND_DOWN作用一样 //如果数字<0 则和ROUND_UP作用一样 System.out.println(round(12.349,2,BigDecimal.ROUND_FLOOR));//12.34 System.out.println(round(-12.3401,2,BigDecimal.ROUND_FLOOR));//-12.35 //ROUND_HALF_UP [这种方法最常用] //如果第3位数字>=5,则第2位数字+1 //备注:只看第3位数字的值,不会考虑第3位之后的小数的 System.out.println(round(12.345,2,BigDecimal.ROUND_HALF_UP));//12.35 System.out.println(round(12.3449,2,BigDecimal.ROUND_HALF_UP));//12.34 System.out.println(round(-12.345,2,BigDecimal.ROUND_HALF_UP));//-12.35 System.out.println(round(-12.3449,2,BigDecimal.ROUND_HALF_UP));//-12.34 //ROUND_HALF_DOWN //如果第3位数字>=5,则做ROUND_UP //如果第3位数字<5,则做ROUND_DOWN System.out.println(round(12.345,2,BigDecimal.ROUND_HALF_DOWN));//12.35 System.out.println(round(12.3449,2,BigDecimal.ROUND_HALF_DOWN));//12.34 System.out.println(round(-12.345,2,BigDecimal.ROUND_HALF_DOWN));//-12.35 System.out.println(round(-12.3449,2,BigDecimal.ROUND_HALF_DOWN));//-12.34 //ROUND_HALF_EVEN //如果第3位是偶数,则做ROUND_HALF_DOWN //如果第3位是奇数,则做ROUND_HALF_UP System.out.println(round(12.346,2,BigDecimal.ROUND_HALF_EVEN));//12.35 System.out.println(round(12.345,2,BigDecimal.ROUND_HALF_EVEN));//12.35 } } |
这篇文章算说的比较详细的了,供参考。
我的简介: 谁说tmd巨蟹座傻来的?我就是tmd巨蟹里边儿最聪明的!!!
您好,请问对于第一个问题,
一个小数,例如1.7777777,或者1.3333333,不管后面的位数是多少,只保留到小数点后第二位,但是不是四舍五入,1.7777777处理后就是1.77,1.3333333处理后就是1.33
能否考虑用乘100再取整作呢?
Hi, tiezhen,
你的意思是小数先乘以100,取整,再除以100是这意思么?应该是ok滴:)
谢谢你的新思路~~~