BigDecimal带精度的运算的两篇文章
转自:http://guoliangqi.iteye.com/blog/670908
之前提到过在商业运算中要使用BigDecimal来进行相关的钱的运算(java中关于浮点运算需要注意的 ),可是实际使用中,简单的用BigDecimal还是出现了一些小问题。
- BigDecimal a = new BigDecimal(998.01);
- BigDecimal b=new BigDecimal("100");
- System.out.println(a.multiply(b));
- BigDecimal aa = new BigDecimal(135.95);
- BigDecimal bb=new BigDecimal("100");
- System.out.println(aa.multiply(bb));
- BigDecimal test = new BigDecimal(4.015);
- BigDecimal test1 = new BigDecimal(100);
- System.out.println(test.multiply(test1));
输出结果为:
- 99800.999999999999090505298227071762084960937500
- 13594.99999999999886313162278383970260620117187500
- 401.49999999999996802557689079549163579940795898437500
出现这种情况的原因就是没有使用BigDecimal的精度。不罗嗦了,直接写上使用BigDecimal的带精度的运算。
比较简单,看代码:
- BigDecimal aa = new BigDecimal(135.95);
- BigDecimal bb=new BigDecimal("100");
- BigDecimal result=aa.multiply(bb);
- System.out.println(result.setScale(2,BigDecimal.ROUND_HALF_EVEN));
此时的输出结果为:
- 13595.00
最主要的是运用了:
- result.setScale(2,BigDecimal.ROUND_HALF_EVEN)
看一下BigDecimal的setScale的api
- setScale
- public BigDecimal setScale(int newScale,
- int roundingMode)
- 返回一个 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,
- 以维护其总值。如果该操作减少标度,则非标度值必须被除(而不是乘),并且该值可以更改;在这种情况下,将指定的
- 舍入模式应用到除法中。
- 注意,由于 BigDecimal 对象是不可变的,此方法的调用不会 导致初始对象被修改,
- 这与使用名为 setX 变异字段 X 方法的常规约定相反。相反,setScale 返回具有适当标度的对象;
- 返回的对象不一定是新分配的。
- 相对于此遗留方法,应优先使用新的 setScale(int, RoundingMode) 方法。
- 参数:
- newScale - 要返回的 BigDecimal 值的标度。
- roundingMode - 要应用的舍入模式。
- 返回:
- 一个 BigDecimal,其标度为指定值,其非标度值可以通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定。
RoundingMode的API
枚举常量摘要
CEILING 向正无限大方向舍入的舍入模式。 |
DOWN 向零方向舍入的舍入模式。 |
FLOOR 向负无限大方向舍入的舍入模式。 |
HALF_DOWN 向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。 |
HALF_EVEN 向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。 |
HALF_UP 向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。 |
UNNECESSARY 用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。 |
UP 远离零方向舍入的舍入模式。 |
看完这些前面那个:
- 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程序员写的。厉害~~~~~~哈哈
- /*
- * 创建日期 2004-10-14
- *
- * 如果需要精确计算,非要用String来够造BigDecimal不可
- */
- package com.lims.actions.testqc.comm;
- /**
- * @author Jstar
- *
- *
- * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
- */
- import java.math.BigDecimal;
- /**
- * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精
- * 确的浮点数运算,包括加减乘除和四舍五入。
- */
- public class Arith {
- //默认除法运算精度
- 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位,以后的数字四舍五入。
- * @param v1 被除数
- * @param v2 除数
- * @return 两个参数的商
- */
- public static double div(double v1, double v2) {
- return div(v1, v2, DEF_DIV_SCALE);
- }
- /**
- * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
- * 定精度,以后的数字四舍五入。
- * @param v1 被除数
- * @param v2 除数
- * @param scale 表示表示需要精确到小数点以后几位。
- * @return 两个参数的商
- */
- public static double div(double v1, double v2, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException("The scale must be a positive integer or zero");
- }
- BigDecimal b = new BigDecimal(Double.toString(v));
- BigDecimal one = new BigDecimal("1");
- return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
- }
BigDecimal带精度的运算的两篇文章的更多相关文章
- 两篇文章带你走入.NET Core 世界:Kestrel+Nginx+Supervisor 部署上云服务器(二)
背景: 上一篇:两篇文章带你走入.NET Core 世界:CentOS+Kestrel+Ngnix 虚拟机先走一遍(一) 已经交待了背景,这篇就省下背景了,这是第二篇文章了,看完就木有下篇了. 直接进 ...
- 两篇文章带你走入.NET Core 世界:CentOS+Kestrel+Ngnix 虚拟机先走一遍(一)
背景: 上一篇:ASP.Net Core on Linux (CentOS7)共享第三方依赖库部署 已经交待了背景,这篇就省下背景了. 折腾的过程分两步: 第一步是:本机跑虚拟机部署试一下: 第二步是 ...
- vnext 技术两篇文章和评论
研究vnext的两篇 好文章,重点看评论! http://www.cnblogs.com/shanyou/p/4589930.html http://www.cnblogs.com/shanyou/p ...
- 有关C#写一个WindowsService的两篇文章
1.http://blog.csdn.net/yysyangyangyangshan/article/details/10515035 上面的这篇文章一共两段,第二段讲的是使用代码来安装发布这个Win ...
- 【Kubernetes】两篇文章 搞懂 K8s 的 fannel 网络原理
近期公司的flannel网络很不稳定,花时间研究了下并且保证云端自动部署的网络能够正常work. 1.网络拓扑 拓扑如下:(点开看大图) 容器网卡通过docker0桥接到flannel0网卡,而每个 ...
- solr中facet及facet.pivot理解(整合两篇文章保留参考)
Facet['fæsɪt]很难翻译,只能靠例子来理解了.Solr作者Yonik Seeley也给出更为直接的名字:导航(Guided Navigation).参数化查询(Paramatic Searc ...
- Android Bootloader LittleKernel的两篇文章 【转】
转自:http://blog.csdn.net/loongembedded/article/details/41747523 2014-12-05 14:37 3599人阅读 评论(2) 收藏 举报 ...
- 学习OpenCV——粒子滤波(网上两篇文章总结)
粒子滤波的理论实在是太美妙了,用一组不同权重的随机状态来逼近复杂的概率密度函数.其再非线性.非高斯系统中具有优良的特性.opencv给出了一个实现,但是没有给出范例,学习过程中发现网络上也找不到.le ...
- Android Bootloader LittleKernel的两篇文章
Android 开发之 ---- bootloader (LK) LK是什么 LK 是 Little Kernel 它是 appsbl (Applications ARM Boot Loader)流程 ...
随机推荐
- kali update can’t found win7 loader
安装win7,kali ,双系统,更新 kali 系统后, grub 找不到win7 ,无法进入win7系统. 解决: grub升级以后为grub2, grub2 默认不能识别win7, 更新一下,即 ...
- linux中hosts文件的修改
转载自http://hi.baidu.com/dillisbest/item/5e0b612d011b4cd40e37f9a6 1. 关于/etc/host,主机名和IP配置文件 Hosts - Th ...
- .net调用java webservice基于JBOSS服务器 学习笔记(一)
1.遇到数组类型或List等复杂数据类型是,需要对其进行包装,就是将复杂数据类型放到一个类里面: public class VOCargoJTWS { /** JT列表 */ private List ...
- poj 1552 Doubles
#include <stdio.h> #include <stdlib.h> ]; int cmp(const void *a, const void *b) { return ...
- spring 占位符 默认值
问题: 今天结合spel使用占位符时,存在没有配置文件中没有配置项的情况,就想给配置一个默认值. 解决方案: public abstract class PlaceholderConfigurerSu ...
- RS-232-C串口通讯协议解析(硬件接口协议)
http://www.dz3w.com/info/interface/0075524.html http://wenku.baidu.com/view/02cc247c27284b73f24250e3 ...
- CString的GetBuffer用法,GetBuffer本质,GetBuffer常见问题解决方法
一.函数原型 CString::GetBuffer LPTSTR GetBuffer( int nMinBufLength ); throw( CMemoryException ); Return V ...
- Spring REST实践之REST基本介绍
REST是什么 REST(REpresentational State Transfer)是一个设计分布式web应用的框架风格,有六个基本原则: Client-Server:应用的参独立与者可分为Cl ...
- EasyUI Accordion下的Panel面板初始化时全部折叠
EasyUI Accordion下的Panel面板有一个属性:selected,默认值为:false.初始化时,若设置'selected:true',则面板默认打开,效果如下: <div tit ...
- Linux 调节屏幕亮度
intel的核心显卡驱动是在 /sys/class/backlight/intel_backlight/ 目录下面的brightness文件中配置的. 可以通过查看max_brightness的值来确 ...