- 浏览: 54604 次
- 性别:
- 来自: 深圳
文章分类
最新评论
之前提到过在商业运算中要使用BigDecimal来进行相关的钱的运算(Java中使用BigDecimal进行浮点数高精度计算),可是实际使用中,简单的用BigDecimal还是出现了一些小问题。
Java代码
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));
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
最主要的是运用了:
Java代码
result.setScale(2,BigDecimal.ROUND_HALF_EVEN)
看一下BigDecimal的setScale的api
BigDecimal的API 写道
可以通过两种类型的操作来处理 BigDecimal 的标度:标度/舍入操作和小数点移动操作。标度/舍入操作(setScale 和 round)返回 BigDecimal,其值近似地(或精确地)等于操作数的值,但是其标度或精度是指定的值;即:它们会增加或减少对其值具有最小影响的存储数的精度。小数点移动操作(movePointLeft 和 movePointRight)返回从操作数创建的 BigDecimal,创建的方法是按指定方向将小数点移动一个指定距离。
Java代码
setScale
public BigDecimal setScale(int newScale,
int roundingMode)
返回一个 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,
以维护其总值。如果该操作减少标度,则非标度值必须被除(而不是乘),并且该值可以更改;在这种情况下,将指定的
舍入模式应用到除法中。
注意,由于 BigDecimal 对象是不可变的,此方法的调用不会 导致初始对象被修改,
这与使用名为 setX 变异字段 X 方法的常规约定相反。相反,setScale 返回具有适当标度的对象;
返回的对象不一定是新分配的。
相对于此遗留方法,应优先使用新的 setScale(int, RoundingMode) 方法。
参数:
newScale - 要返回的 BigDecimal 值的标度。
roundingMode - 要应用的舍入模式。
返回:
一个 BigDecimal,其标度为指定值,其非标度值可以通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定。
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
远离零方向舍入的舍入模式。
看完这些前面那个:
Java代码
result.setScale(2,BigDecimal.ROUND_HALF_EVEN)
的意思就是,将这个BigDecimal小数点后保留2位,四舍五入的方式为向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
ok,记录完毕,看来以后要用bigDecimal还必须要用它这个scale的功能来保证精度,不然还是跟double一样会出现悲剧!
Java代码
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));
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
最主要的是运用了:
Java代码
result.setScale(2,BigDecimal.ROUND_HALF_EVEN)
看一下BigDecimal的setScale的api
BigDecimal的API 写道
可以通过两种类型的操作来处理 BigDecimal 的标度:标度/舍入操作和小数点移动操作。标度/舍入操作(setScale 和 round)返回 BigDecimal,其值近似地(或精确地)等于操作数的值,但是其标度或精度是指定的值;即:它们会增加或减少对其值具有最小影响的存储数的精度。小数点移动操作(movePointLeft 和 movePointRight)返回从操作数创建的 BigDecimal,创建的方法是按指定方向将小数点移动一个指定距离。
Java代码
setScale
public BigDecimal setScale(int newScale,
int roundingMode)
返回一个 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,
以维护其总值。如果该操作减少标度,则非标度值必须被除(而不是乘),并且该值可以更改;在这种情况下,将指定的
舍入模式应用到除法中。
注意,由于 BigDecimal 对象是不可变的,此方法的调用不会 导致初始对象被修改,
这与使用名为 setX 变异字段 X 方法的常规约定相反。相反,setScale 返回具有适当标度的对象;
返回的对象不一定是新分配的。
相对于此遗留方法,应优先使用新的 setScale(int, RoundingMode) 方法。
参数:
newScale - 要返回的 BigDecimal 值的标度。
roundingMode - 要应用的舍入模式。
返回:
一个 BigDecimal,其标度为指定值,其非标度值可以通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定。
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
远离零方向舍入的舍入模式。
看完这些前面那个:
Java代码
result.setScale(2,BigDecimal.ROUND_HALF_EVEN)
的意思就是,将这个BigDecimal小数点后保留2位,四舍五入的方式为向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
ok,记录完毕,看来以后要用bigDecimal还必须要用它这个scale的功能来保证精度,不然还是跟double一样会出现悲剧!
发表评论
-
java中如何进行高精度运算
2011-08-31 20:32 760import java.math.BigDecimal; im ... -
win7下安装vs2008
2011-01-09 23:28 824在win7下安装VS2008有点不太让人愉快,不过白痴还是找到 ... -
设置响应头字段的些许应用
2010-12-11 13:04 1031禁止浏览器缓存当前文档内容 只要增加如下的响应头字段: r ... -
正则表达式
2010-12-11 12:39 555整理资料如下: \\ 反斜杠 \t 间隔 ('\u0009' ... -
应该懂的基础问题
2010-12-11 12:14 658问题一:我声明了什么! String s = &quo ... -
Java中的堆栈
2010-12-11 10:59 609Java把内存划分成两种:一种是栈内存,一种是堆内存。 ... -
Java IO 小结
2010-12-11 10:51 559什么是数据流 ----------数据流是指所有的数据通信通道 ... -
字符转换
2010-11-30 20:43 600问:怎样将GBK 编码的汉字转换成为 UTF-8 编码的汉 ... -
进制转换
2010-11-30 20:42 760计算机操作里面时常要牵涉到二进制、十进制、十六进制等。特别是在 ... -
多叉树解决复杂表头问题
2010-11-30 20:21 734现代化WEB项目中少不了要用到报表展现.对于中国式报表来说,复 ... -
关于java编码的转换
2010-11-30 20:17 547问:怎样将GBK 编码的汉字转换成为 UTF-8 编码的汉 ... -
编译器报:未调用原型函数(是有意用变量定义的吗?)(本文为原创,转载清注明出外)
2010-11-30 20:08 1779MSDN解释:编译器检测到未使用的函数原型。如果有意将该原型作 ... -
C++类型转换运算符重载
2010-11-30 20:06 819在C++中有一个特殊的运算符重载方法--类型转换运算符重载,形 ... -
ATL分解字符串
2010-11-30 20:05 718一个简单的分解字符串的方法: Code vector< ... -
java字符集(三)之java.io
2010-11-30 20:04 896java IO 的输出分两种,字节流: InputStream ... -
java字符集(二)
2010-11-30 20:03 631知道java的字符集编码,那么java是怎么读取内存中的字节转 ... -
编码字符集与字符集编码的区别(转)
2010-11-30 20:03 631需要再一次强调的是,无论历史上的UCS还是现如今的Unicod ... -
Unicode与UCS的历史恩怨(转载)
2010-11-30 19:59 525ASCII及相关标准 ... -
Java字符集(一)
2010-11-30 19:57 631UNICODE,GBK和BIG5就是编码的值,而utf-8,u ...
相关推荐
所谓高精度地图(也称为高精度地图),实际上是和普通导航电子地图相对而言的服务于自动驾驶系统的专题地图。高精度地图可以分为两个层级:静态高精度地图和动态高精度地图。静态高精度地图处于底层,是目前研发的...
写高精度运算和矩阵乘法的时候,把常用的都封装在一起,写在一个头文件里方便使用.. 矩阵(matrix) 高精度(longnum) 重载了运算符+,-,*,/ 适用运算: 矩阵相乘 高精度数+高精度数 高精度数+低精度数 高精度数×高...
通过使用硬件支持高精度计时器以及CPU主频实现高精度定时器,计时器
1307:【例1.3】高精度乘法 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 4358 通过数: 1440 【题目描述】 输入两个高精度正整数M和N(M和N均小于100位)。求这两个高精度数的积。 【输入】 输入两个高精度正...
这个版本的高精度整数库不仅支持高精度除高精度,同时修复了减法计算中的一个严重的bug。并支持高精度类型与其他一切可转换为高精度类型的类型(int,long long,unsignd,string)进行混合运算。同时,全面优化了除法、...
Java高精度计算Java高精度计算Java高精度计算Java高精度计算Java高精度计算Java高精度计算Java高精度计算Java高精度计算Java高精度计算Java高精度计算Java高精度计算Java高精度计算
qt及windows提供的定时器在ms级延时时是无法精确到ms的,因此写了一个获取cpu的高精度定时器,仅限在pc机上使用,因为会占用cpu资源不建议在单片机及arm上使用
Windows平台高精度定时器封装类,最高精度可达1ms。
c++高精度
位移传感技术是一项对现代科学研究和工业生产有着重要影响的传感技术,在高精度数控机床、航空航天、石油化工等国民经济各重要领域有着广泛应用。为符合各行各业尤其是现代化工业生产日益增长的需求,位移测量正朝着高...
高精度 加法 减法 乘法 除法。你想要的全部囊括了!
C++高精度减法运算(文件流输入输出),支持正整数运算。经VC++及DevC++5编译通过,测试无误。
基于高精度-小量程的电子秤设计分析.pdf基于高精度-小量程的电子秤设计分析.pdf基于高精度-小量程的电子秤设计分析.pdf基于高精度-小量程的电子秤设计分析.pdf基于高精度-小量程的电子秤设计分析.pdf基于高精度-小...
高精度压位 #include #include #include using namespace std; const int maxleng=500; class BigInt { private: int leng; int num[maxleng]; public:
基于计数器和labview高精度软件计时vi实现两个脉冲信号间的高精度时间测量(High precision time measurement between two pulse signals based on counter and LabVIEW high precision software timing VI)
高精度计算 高精度加法 高精度减法 高精度乘法 高精度除法
蓝牙AOA高精度定位技术白皮书
windows自带的定时器精度一般在10ms量级,精确度不足,在部分需要高精度定时的应用场合中,需要一种更高精度的定时器。 该高精度定时器能提供约1ms的定时精度,在轻负荷条件下的定时精度较稳定。 关键的是,该定时器...
这是一个C#高精度计时器类的实现.平时C#的Timer控件精度只有1/64秒,如果您需要更高的精度则建议使用此类.不完善的地方请改正