转自:http://guoliangqi.iteye.com/blog/670908

之前提到过在商业运算中要使用BigDecimal来进行相关的钱的运算(java中关于浮点运算需要注意的 ),可是实际使用中,简单的用BigDecimal还是出现了一些小问题。

  1. BigDecimal a = new BigDecimal(998.01);
  2. BigDecimal b=new BigDecimal("100");
  3. System.out.println(a.multiply(b));
  4. BigDecimal aa = new BigDecimal(135.95);
  5. BigDecimal bb=new BigDecimal("100");
  6. System.out.println(aa.multiply(bb));
  7. BigDecimal test = new BigDecimal(4.015);
  8. BigDecimal test1 = new BigDecimal(100);
  9. System.out.println(test.multiply(test1));

输出结果为:

  1. 99800.999999999999090505298227071762084960937500
  2. 13594.99999999999886313162278383970260620117187500
  3. 401.49999999999996802557689079549163579940795898437500

出现这种情况的原因就是没有使用BigDecimal的精度。不罗嗦了,直接写上使用BigDecimal的带精度的运算。

比较简单,看代码:

  1. BigDecimal aa = new BigDecimal(135.95);
  2. BigDecimal bb=new BigDecimal("100");
  3. BigDecimal result=aa.multiply(bb);
  4. System.out.println(result.setScale(2,BigDecimal.ROUND_HALF_EVEN));

此时的输出结果为:

  1. 13595.00

最主要的是运用了:

  1. result.setScale(2,BigDecimal.ROUND_HALF_EVEN)

看一下BigDecimal的setScale的api

BigDecimal的API 写道
可以通过两种类型的操作来处理 BigDecimal 的标度:标度/舍入操作和小数点移动操作。标度/舍入操作(setScale 和 round)返回 BigDecimal,其值近似地(或精确地)等于操作数的值,但是其标度或精度是指定的值;即:它们会增加或减少对其值具有最小影响的存储数的精度。小数点移动操作(movePointLeft 和 movePointRight)返回从操作数创建的 BigDecimal,创建的方法是按指定方向将小数点移动一个指定距离。
  1. setScale
  2. public BigDecimal setScale(int newScale,
  3. int roundingMode)
  4. 返回一个 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,
  5. 以维护其总值。如果该操作减少标度,则非标度值必须被除(而不是乘),并且该值可以更改;在这种情况下,将指定的
  6. 舍入模式应用到除法中。
  7. 注意,由于 BigDecimal 对象是不可变的,此方法的调用不会 导致初始对象被修改,
  8. 这与使用名为 setX 变异字段 X 方法的常规约定相反。相反,setScale 返回具有适当标度的对象;
  9. 返回的对象不一定是新分配的。
  10. 相对于此遗留方法,应优先使用新的 setScale(int, RoundingMode) 方法。
  11. 参数:
  12. newScale - 要返回的 BigDecimal 值的标度。
  13. roundingMode - 要应用的舍入模式。
  14. 返回:
  15. 一个 BigDecimal,其标度为指定值,其非标度值可以通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定。

RoundingMode的API

枚举常量摘要

CEILING   
          向正无限大方向舍入的舍入模式。
DOWN

  
          向零方向舍入的舍入模式。
FLOOR

  
          向负无限大方向舍入的舍入模式。
HALF_DOWN

  
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。
HALF_EVEN

  
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
HALF_UP

  
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。
UNNECESSARY

  
          用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。
UP

  
          远离零方向舍入的舍入模式。

看完这些前面那个:

  1. result.setScale(2,BigDecimal.ROUND_HALF_EVEN)

的意思就是,将这个BigDecimal小数点后保留2位,四舍五入的方式为向最接近数字方向舍入的舍入 模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

ok,记录完毕,看来以后要用bigDecimal还必须要用它这个scale的功能来保证精度,不然还是跟double一样会出现悲剧!

————————————————————————————————————————————————————

转自:http://blog.csdn.net/lujinan858/article/details/4371099

1.

String myMoney = "100.0128";

BigDecimal money= new BigDecimal(myMoney);

//设置精度,以及舍入规则 
  money= money.setScale(2, BigDecimal.ROUND_HALF_UP);

System.out.println(money);

//100.01

2. double myMoney = 100.0128;

myMoney  = Math.round(myMoney  * 100) / (double) 100  ;

BigDecimal money= new BigDecimal(myMoney);

System.out.println(money); //后面则有很多的小数

//为了保证小数位数为2位

BigDecimal money= new BigDecimal(Double.toString(myMoney));

System.out.println(money); //小数位数则为2位

这个类确实好用。在网上找到的,是一个女Java程序员写的。厉害~~~~~~哈哈

  1. /*
  2. * 创建日期 2004-10-14
  3. *
  4. * 如果需要精确计算,非要用String来够造BigDecimal不可
  5. */
  6. package com.lims.actions.testqc.comm;
  7. /**
  8. * @author Jstar
  9. *
  10. *
  11. * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
  12. */
  13. import java.math.BigDecimal;
  14. /**
  15. * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精
  16. * 确的浮点数运算,包括加减乘除和四舍五入。
  17. */
  18. public class Arith {
  19. //默认除法运算精度
  20. private static final int DEF_DIV_SCALE = 10;
  21. //这个类不能实例化
  22. private Arith() {
  23. }
  24. /**
  25. * 提供精确的加法运算。
  26. * @param v1 被加数
  27. * @param v2 加数
  28. * @return 两个参数的和
  29. */
  30. public static double add(double v1, double v2) {
  31. BigDecimal b1 = new BigDecimal(Double.toString(v1));
  32. BigDecimal b2 = new BigDecimal(Double.toString(v2));
  33. return b1.add(b2).doubleValue();
  34. }
  35. /**
  36. * 提供精确的减法运算。
  37. * @param v1 被减数
  38. * @param v2 减数
  39. * @return 两个参数的差
  40. */
  41. public static double sub(double v1, double v2) {
  42. BigDecimal b1 = new BigDecimal(Double.toString(v1));
  43. BigDecimal b2 = new BigDecimal(Double.toString(v2));
  44. return b1.subtract(b2).doubleValue();
  45. }
  46. /**
  47. * 提供精确的乘法运算。
  48. * @param v1 被乘数
  49. * @param v2 乘数
  50. * @return 两个参数的积
  51. */
  52. public static double mul(double v1, double v2) {
  53. BigDecimal b1 = new BigDecimal(Double.toString(v1));
  54. BigDecimal b2 = new BigDecimal(Double.toString(v2));
  55. return b1.multiply(b2).doubleValue();
  56. }
  57. /**
  58. * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
  59. * 小数点以后10位,以后的数字四舍五入。
  60. * @param v1 被除数
  61. * @param v2 除数
  62. * @return 两个参数的商
  63. */
  64. public static double div(double v1, double v2) {
  65. return div(v1, v2, DEF_DIV_SCALE);
  66. }
  67. /**
  68. * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
  69. * 定精度,以后的数字四舍五入。
  70. * @param v1 被除数
  71. * @param v2 除数
  72. * @param scale 表示表示需要精确到小数点以后几位。
  73. * @return 两个参数的商
  74. */
  75. public static double div(double v1, double v2, int scale) {
  76. if (scale < 0) {
  77. throw new IllegalArgumentException("The scale must be a positive integer or zero");
  78. }
  79. BigDecimal b = new BigDecimal(Double.toString(v));
  80. BigDecimal one = new BigDecimal("1");
  81. return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
  82. }

BigDecimal带精度的运算的两篇文章的更多相关文章

  1. 两篇文章带你走入.NET Core 世界:Kestrel+Nginx+Supervisor 部署上云服务器(二)

    背景: 上一篇:两篇文章带你走入.NET Core 世界:CentOS+Kestrel+Ngnix 虚拟机先走一遍(一) 已经交待了背景,这篇就省下背景了,这是第二篇文章了,看完就木有下篇了. 直接进 ...

  2. 两篇文章带你走入.NET Core 世界:CentOS+Kestrel+Ngnix 虚拟机先走一遍(一)

    背景: 上一篇:ASP.Net Core on Linux (CentOS7)共享第三方依赖库部署 已经交待了背景,这篇就省下背景了. 折腾的过程分两步: 第一步是:本机跑虚拟机部署试一下: 第二步是 ...

  3. vnext 技术两篇文章和评论

    研究vnext的两篇 好文章,重点看评论! http://www.cnblogs.com/shanyou/p/4589930.html http://www.cnblogs.com/shanyou/p ...

  4. 有关C#写一个WindowsService的两篇文章

    1.http://blog.csdn.net/yysyangyangyangshan/article/details/10515035 上面的这篇文章一共两段,第二段讲的是使用代码来安装发布这个Win ...

  5. 【Kubernetes】两篇文章 搞懂 K8s 的 fannel 网络原理

    近期公司的flannel网络很不稳定,花时间研究了下并且保证云端自动部署的网络能够正常work. 1.网络拓扑 拓扑如下:(点开看大图)  容器网卡通过docker0桥接到flannel0网卡,而每个 ...

  6. solr中facet及facet.pivot理解(整合两篇文章保留参考)

    Facet['fæsɪt]很难翻译,只能靠例子来理解了.Solr作者Yonik Seeley也给出更为直接的名字:导航(Guided Navigation).参数化查询(Paramatic Searc ...

  7. Android Bootloader LittleKernel的两篇文章 【转】

    转自:http://blog.csdn.net/loongembedded/article/details/41747523 2014-12-05 14:37 3599人阅读 评论(2) 收藏 举报 ...

  8. 学习OpenCV——粒子滤波(网上两篇文章总结)

    粒子滤波的理论实在是太美妙了,用一组不同权重的随机状态来逼近复杂的概率密度函数.其再非线性.非高斯系统中具有优良的特性.opencv给出了一个实现,但是没有给出范例,学习过程中发现网络上也找不到.le ...

  9. Android Bootloader LittleKernel的两篇文章

    Android 开发之 ---- bootloader (LK) LK是什么 LK 是 Little Kernel 它是 appsbl (Applications ARM Boot Loader)流程 ...

随机推荐

  1. MemoryMappingFile泄漏分析过程

    最近项目突然收到了一个紧急的问题报告 - 用户在进行某些关键操作的时候整个软件突然就crash掉了.幸好产品继承了自动抓取dump的功能...   收到dump之后,通过windbg打开,查看相应的c ...

  2. R语言简单入门

    一.运行R语言可以做哪些事? 1.探索性数据分析(将数据绘制图表) 2.统计推断(根据数据进行预测) 3.回归分析(对数据进行拟合分析) 4.机器学习(对数据集进行训练和预测) 5.数据产品开发 二. ...

  3. python异常以及面向对象编程

    一.面向对象 需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__na ...

  4. NServiceBus-日志

    默认的日志 NServiceBus一些有限,固执己见,内置的日志记录. 默认的日��行为如下: 控制台 所有 Info(及以上)消息将被输送到当前的控制台. 错误将会写 ConsoleColor.Re ...

  5. UDP广域网,局域网通信-原理分析,穿透技术

    一.UDP局域网通信. 这个比较简单,关于局域网中的2台或者更多的计算机之间的UDP通信,网络上一大把,直接复制粘贴就可以使用,原理也非常简单.所以,本文不做详细介绍. 二.UDP广域通信(包括路由器 ...

  6. EasyUI DataGrid 窗口大小自适用--------------未测试

    EasyUI 新版本里添加了 fit 属性,不需要老版本的那么复杂,重新load DataGrid.但是昨天用的时间发现只有一个DataGrid的时候用fit:true 很好使,但是如果有其它元素,如 ...

  7. 【转】大数据以及Hadoop相关概念介绍

    原博文出自于: http://www.cnblogs.com/xdp-gacl/p/4230220.html 感谢! 一.大数据的基本概念 1.1.什么是大数据 大数据指的就是要处理的数据是TB级别以 ...

  8. LightOJ 13361336 - Sigma Function (找规律 + 唯一分解定理)

    http://lightoj.com/volume_showproblem.php?problem=1336 Sigma Function Time Limit:2000MS     Memory L ...

  9. oracle学习 九 游标的使用(持续更)

    为什么要使用? 笔者查阅了一些资料之后得到的结论是, 关系型数据库是面向集合的,而游标是面向行的,游标可对取出来的集合(结果集)中每一行进行相同或不同的操作,还提供对基于游标位置而对表中数据进行删除或 ...

  10. 浅析 JavaScript 中的闭包(Closures)

    a { text-decoration: none; color: #4094c7 } h4,h5 { margin: 0; font-weight: 700; color: inherit; lin ...