java java中的bigdecimall 四舍五入的bug?

java bigdecimal 四舍五入_百度知道
java bigdecimal 四舍五入
java bigdecimal怎么四舍五入
不仅只setS&#47.setScale(2.ROUND_HALF_UP)bigDecimal =
bigD&#47,四舍五入后要重新赋值;保留两位小数且向上进位的四舍五入, BigDecimal
其他类似问题
为您推荐:
bigdecimal的相关知识
其他1条回答
bigdecimal.ROUND_HALF_UP就是四舍五入后的数据
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁BigDecimal在实际项目的应用及遇到的问题 - 问道江湖 - ITeye技术网站
博客分类:
我们都知道,java中对大小数,高精度的计算都会用到BigDecimal.但是在实际应用中,运用BigDecimal还是会遇到一些问题.下面说一下我在项目中怎么样BigDecimal和遇到的一些问题.
1. 对商品的价格进行格式化,比如所有商品的价格保留两位小数
* @param bd
商品的价格
* @param num 保留几位小数,如num = 2
public static String formatPrice(BigDecimal bd,int num){
if(bd == null || num & 0){
bd = bd.setScale(num, BigDecimal.ROUND_HALF_UP);
return bd + "";
其中BigDecimal.ROUND_HALF_UP表示采用"四舍五入"的模式处理价格
2. 将商品的价格由元转为分,便于前端分隔展现
* 元转换为分
* @param bd 商品的价格
public static String yuanToCent(BigDecimal bd){
if(bd == null){
bd = bd.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_EVEN);
return bd + "";
其中setScale(0, BigDecimal.ROUND_HALF_EVEN)表示采用"四舍五入"的模式处理价格,并且结果不保留小数.
3. 获取缓存命中率
* 缓存命中率
public static String getHitRate(){
BigDecimal a = new BigDecimal(cacheCount.longValue()*100);
BigDecimal b = new BigDecimal(sumCount.longValue());
if(sumCount.longValue() & 0){
return "%" + (a.divide(b, 2, BigDecimal.ROUND_HALF_EVEN));
return "0";
4. BigDecimal中对于等于"0"的判断
在 BigDecimal中,new BigDecimal("0")与new BigDecimal("0.0"),new BigDecimal(0)与new BigDecimal("0.0")都是不等的.但是本质上,它们都是"0".怎么对是否等于"0"进行判断?将BigDecimal类型的值通过调用doubleValue()方法转换为double类型进行比较或通过上面的方法yuanToCent转换一下比较就能解决这个问题.
用BigDecimal进行除法计算时抛出java.lang.ArithmeticException: Non-terminati no exact representable decimal result异常.
比如用new BigDecimal(30).divide(new BigDecimal(7))就会抛这个异常,异常原因:BigDecimal的divide方法进行除法时当不整除,出现无限循环小数时,就会抛这个异常.
解决办法:给divide设置精确的小数点位数或"舍入"模式,如
new BigDecimal(30).divide(new
BigDecimal(7),BigDecimal.ROUND_HALF_UP).setScale(2,BigDecimal.ROUND_HALF_UP)或
new BigDecimal(30).divide(new BigDecimal(7),2,BigDecimal.ROUND_HALF_UP)
建议采用第二种方式,因为第二种方式的结果精度更高
另外,要注意BigDecimal跟String一样,是不可改变的,比如BigDecimal对象执行setScale(), add()等操作都会返回一个新的BigDecimal.
hellostory 写道liudeh_009 写道hellostory 写道引用& 4. BigDecimal中对于等于"0"的判断System.out.println(new BigDecimal("0").compareTo(new BigDecimal("0.0")));PS:前台打印BigDecimal数据时,若有小数点,则小数点后面可能会出现很多个0,你怎么处理的?setScale方法可以设置包含小数点的位数这我知道,但有一个问题:比如后台需要精度达到6个小数点,如果你设置精度为6位小数,那么前台显示时,你会发现“5.67”仍然会显示“5.670000”如果只是想把后面没有意义的0去掉,把结果转成double类型输出就可以了所有就得多写一个FormBean,或多个字段等
liudeh_009 写道hellostory 写道引用& 4. BigDecimal中对于等于"0"的判断System.out.println(new BigDecimal("0").compareTo(new BigDecimal("0.0")));PS:前台打印BigDecimal数据时,若有小数点,则小数点后面可能会出现很多个0,你怎么处理的?setScale方法可以设置包含小数点的位数这我知道,但有一个问题:比如后台需要精度达到6个小数点,如果你设置精度为6位小数,那么前台显示时,你会发现“5.67”仍然会显示“5.670000”如果只是想把后面没有意义的0去掉,把结果转成double类型输出就可以了
hellostory 写道引用& 4. BigDecimal中对于等于"0"的判断System.out.println(new BigDecimal("0").compareTo(new BigDecimal("0.0")));PS:前台打印BigDecimal数据时,若有小数点,则小数点后面可能会出现很多个0,你怎么处理的?setScale方法可以设置包含小数点的位数这我知道,但有一个问题:比如后台需要精度达到6个小数点,如果你设置精度为6位小数,那么前台显示时,你会发现“5.67”仍然会显示“5.670000”
引用& 4. BigDecimal中对于等于"0"的判断System.out.println(new BigDecimal("0").compareTo(new BigDecimal("0.0")));PS:前台打印BigDecimal数据时,若有小数点,则小数点后面可能会出现很多个0,你怎么处理的?setScale方法可以设置包含小数点的位数
第4条没new BigDecimal("0.0"),new BigDecimal(0)不等是指业务上还是程序上?compareTo方法呢?程序上的,我以前不知道可以用compareTo,现在发现用compareTo比较更简单,刚才查了一下,发现compareTo方法不需要两个BigDecimal值具有相同的精度就可以比较大小
& 4. BigDecimal中对于等于"0"的判断System.out.println(new BigDecimal("0").compareTo(new BigDecimal("0.0")));PS:前台打印BigDecimal数据时,若有小数点,则小数点后面可能会出现很多个0,你怎么处理的?
liudeh_009
浏览: 100068 次
来自: 杭州
关于eclipse插件版的使用,少了一张图!
非常地棒!很敬佩!
besterzhao 写道冒昧问一句,processExpir ...
冒昧问一句,processExpires() 从哪里看出来“过 ...
..大神,能教我下怎么用么。。。看了半天,把那个包加到项目中? ...页面导航:
→ 正文内容 java中BigDecimal的操作
java中BigDecimal的操作方法
这篇文章主要介绍了java中BigDecimal的操作方法,较为详细的分析了BigDecimal类在进行商业计算时的应用方法,精度以及注意事项等问题,需要的朋友可以参考下
本文实例讲述了java中BigDecimal的操作方法。分享给大家供大家参考。具体分析如下:
由于double,float的精度不够,因此在进行商业计算的时候要使用的BigDecimal。BigDecimal对象创建如下:
代码如下:BigDecimal b = new BigDecimal("12.000001");
System.out.println(b);
输出结果为:12.000001;
BigDecimal在创建的时候可以传入String和double,但是最好使用String,至于原因看看如下代码就知道了:
代码如下:BigDecimal b = new BigDecimal("12.000001");
System.out.println(b);
BigDecimal c = new BigDecimal(12.01);
System.out.println(c);
运行结果为:
可以看出在传入double的时候精度会丢失。
BigDecimal其他操作如下:
代码如下:&&& //加法
&&& public static BigDecimal add(String num1, String num2) {
&&&&&&& BigDecimal bd1 = new BigDecimal(num1);
&&&&&&& BigDecimal bd2 = new BigDecimal(num2);
&&&&&&& return bd1.add(bd2);
&&& //减法
&&& public static BigDecimal subtract(String num1, String num2) {
&&&&&&& BigDecimal bd1 = new BigDecimal(num1);
&&&&&&& BigDecimal bd2 = new BigDecimal(num2);
&&&&&&& return bd1.subtract(bd2);
&&& //乘法
&&& public static BigDecimal multiply(String num1, String num2) {
&&&&&&& BigDecimal bd1 = new BigDecimal(num1);
&&&&&&& BigDecimal bd2 = new BigDecimal(num2);
&&&&&&& return bd1.multiply(bd2);
&&& //除法
&&& public static BigDecimal divide(String num1, String num2, int i) {
&&&&&&& BigDecimal bd1 = new BigDecimal(num1);
&&&&&&& BigDecimal bd2 = new BigDecimal(num2);
&&&&&&& // i是要保留的位数, BigDecimal.ROUND_HALF_UP 表示四舍五入的规则
&&&&&&& return bd1.divide(bd2, i, BigDecimal.ROUND_HALF_DOWN);&
需要强调一下除法,第三个参数为是否四舍五入,
ROUND_HALF_DOWN表示遇5不进1,即1.5-&1;
ROUND_HALF_UP表示遇5进1,即1.5-&2;
但是有点需要注意:
当我们使用ROUND_HALF_DOWN时
代码如下:System.out.println(this.divide("67.75", "5",4));
System.out.println(this.divide("67.75", "5",1));
System.out.println("-------");
System.out.println(this.divide("67.751", "5",4));
System.out.println(this.divide("67.751", "5",1));
运行结果如下:
我就纳闷了,按道理第二个结果应该是13.5啊!怎么成了13.6。后来经过多次测试,想了一下,这个四舍五入不是按照精度位后面移位与5做比较,而是按照精度位后的所有的数据与5做比较,也就是说:13.5500精确到一位,则用0.0500与5比较,而13.5502精确到一位,则用0.0502与5比较,比5大,所以就向上收。
希望本文所述对大家的Java程序设计有所帮助。
您可能感兴趣的文章:
上一篇:下一篇:
最 近 更 新
热 点 排 行
12345678910想要一个跟我们传统学的四舍五入的方法,网上多说下面的方法可以用,我测了下,发现有很多问题啊。当所要求的小数位小于等于1位时没错误,但当小数位2位以上就有问题了,下面是测试用例,及结果。测试发现当所要小数位为2位时,遇到偶数进1,奇数不进。十位数不位空时也是如此。 谁说下这个啥回事?顺便求其他传统格式化方法。DecimalFormat这个类也不行,奇数进1偶数不进的
public class test {
public static void main(String[] args) {
double a = 1.5;
double b = 2.5;
double c = 1.35;
double d = 2.35;
double e = 2.355;
double f = 2.345;
double g= 12.35;
BigDecimal bigA =new BigDecimal(a).setScale(0, BigDecimal.ROUND_HALF_UP);
BigDecimal bigB =new BigDecimal(b).setScale(0, BigDecimal.ROUND_HALF_UP);
BigDecimal bigC =new BigDecimal(c).setScale(1, BigDecimal.ROUND_HALF_UP);
BigDecimal bigD =new BigDecimal(d).setScale(1, BigDecimal.ROUND_HALF_UP);
BigDecimal bigE=new BigDecimal(e).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal bigF=new BigDecimal(f).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal bigG=new BigDecimal(g).setScale(1, BigDecimal.ROUND_HALF_UP);
System.out.println("test A:"+bigA.doubleValue());
System.out.println("test B:"+bigB.doubleValue());
System.out.println("test C:"+bigC.doubleValue());
System.out.println("test D:"+bigD.doubleValue());
System.out.println("test E:"+bigE.doubleValue());
System.out.println("test F:"+bigF.doubleValue());
System.out.println("test G:"+bigG.doubleValue());
输出结果:&&&&&&&& 想要的结果
test A:2.0&&&&&&&& 2.0
test B:3.0&&&&&&&& 3.0
test C:1.4&&&&&&&& 1.4
test D:2.4&&&&&&&& 2.4
test E:2.35&& X&&& 2.36
test F:2.35&&&&&&& 2.35
test G:12.3&& X&&& 12.4
采纳的答案
你定义的方式有问题。
double g= 12.35;& 定义了一个g=12.44449,假如是这个数
new BigDecimal(g)&& g还是12.44449
new BigDecimal(g).setScale(1, BigDecimal.ROUND_HALF_UP);&& 12.34
正确的定义方式是使用字符串构造函数
new BigDecimal("12.35").setScale(1, BigDecimal.ROUND_HALF_UP)
可以看下这个博客。
/admin/blogs/670908
public static double round(double value,int scale){&&
if(scale&0){&&
throw new IllegalArgumentException(&&
The scale must be a positive integer or zero");&&
BigDecimal b = new BigDecimal(Double.toString(value));&&
BigDecimal one = new BigDecimal("1");&&
return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();&&
试试上面的方法吧!!!
已解决问题
未解决问题关于java的BigDecimal门类经Hessian发布出现Bug的示例 - 软件架构设计当前位置:& &&&关于java的BigDecimal门类经Hessian发布出现Bug的示关于java的BigDecimal门类经Hessian发布出现Bug的示例&&网友分享于:&&浏览:181次关于java的BigDecimal类型经Hessian发布出现Bug的示例
我用的Hessian是Hessian 4.0.7版本我们用它与spring集成以下是web.xml内容
&?xml version="1.0" encoding="UTF-8"?&
&web-app version="2.4"
xmlns="/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="/xml/ns/j2ee
/xml/ns/j2ee/web-app_2_4.xsd"&
&context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&/WEB-INF/classes/*-context.xml&/param-value&
&/context-param&
&listener&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class&
&/listener&
&servlet-name&remoting&/servlet-name&
&servlet-class&org.springframework.web.servlet.DispatcherServlet&/servlet-class&
&init-param&
&param-name&contextConfigLocation&/param-name&
&param-value&/WEB-INF/classes/*-remote.xml&/param-value&
&/init-param&
&load-on-startup&1&/load-on-startup&
&/servlet&
&servlet-mapping&
&servlet-name&remoting&/servlet-name&
&url-pattern&/remoting/*&/url-pattern&
&/servlet-mapping&
&welcome-file-list&
&welcome-file&index.jsp&/welcome-file&
&/welcome-file-list&
&/web-app&
以下是Hessian发布配置(common-remote.xml):
&?xml version="1.0" encoding="gb2312"?&
&beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"&
此文件定义上下文内容,各模块需各自按以下指定的文件名在各模块的src文件夹下维护、管理上下文内容。
此文件只作管理用途,不允许随意修改!
&bean name="/remoteLoginService" class="org.springframework.remoting.caucho.HessianServiceExporter"&
&property name="service" ref="fap.loginService"/&
&property name="serviceInterface" value="mon.ILoginService"/&
&!-- 用户管理 --&
&bean name="/remoteUserService" class="org.springframework.remoting.caucho.HessianServiceExporter"&
&property name="service" ref="fap.userService"/&
&property name="serviceInterface" value="mon.IUserService"/&
&bean name="/remoteTest" class="org.springframework.remoting.caucho.HessianServiceExporter"&
&property name="service" ref="testbean"/&
&property name="serviceInterface" value="mon.ITestService"/&
bean的定义我们只关注我们的测试类(common-context.xml):
&bean id="testbean" class="mon.bs.TestService"&&/bean&
接口的定义:
import java.math.BigD
public interface ITestService {
public BigDecimal testBig();
public float testfloat();
public double testdouble();
接口实现类的定义:
package mon.
import mon.ITestS
import java.math.BigD
public class TestService implements ITestService {
public BigDecimal testBig() {
BigDecimal big=new BigDecimal( "10.90944" );
System.out.println("服务端:"+big);
public double testdouble(){
return 10.123d;
public float testfloat(){
return 10.123f;
测试代码:
public static void main(String[] args) throws Exception {
String url = "http://localhost:8080/realware/remoting/remoteTest";
HessianProxyFactory factory = new HessianProxyFactory();
ITestService test = (ITestService) factory.create(ITestService.class,url);
BigDecimal bi=test.testBig();
System.out.println(test.testdouble());
System.out.println(test.testfloat());
System.out.println(new BigDecimal(bi.toString()));
BigDecimal big=new BigDecimal("10.123");
System.out.println(big.toString());
最后服务发布后,测试结果为:
服务器打印:
服务端:10.90944
我们可以看到Hessian对于BigDemical类型的序列化后的传输是个大bug,它保留了它的精度,但数值全是0.
有没有相应的解决方案呢?这应该是Hessian的一个bug,用String传值吧
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有

我要回帖

更多关于 java bigdecimal 乘法 的文章

 

随机推荐