精华内容
下载资源
问答
  • BigDecimal 比较 0 ,负数正数

    千次阅读 2019-06-14 14:51:20
    BigDecimal money = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP); //signum():-1 负数,0 0 ,1 正数 if (money.signum() == -1) { System.out.println("这是一个负数"); ...
     BigDecimal money = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP);
            
            //signum():-1 负数,0 0 ,1 正数
            if (money.signum() == -1) {
                System.out.println("这是一个负数");
            }else if(money.signum() == 0){
                System.out.println("这是一个0");
            }else {
                System.out.println("这是一个正数");
            }

     

    展开全文
  • 具体代码如下, 因本人...BigDecimal s = (BigDecimal) list.get(i).get("HK_AMT"); //BigDecimal类型数字 Double dValue=-s.doubleValue(); //转为Double String bValue=BigDecimal.valueOf(dValue).toPlainStrin...

    具体代码如下, 因本人java比不是很好。故没办法解释原理

    BigDecimal s = (BigDecimal) list.get(i).get("HK_AMT"); //BigDecimal类型数字
    Double dValue=-s.doubleValue(); //转为Double
    String bValue=BigDecimal.valueOf(dValue).toPlainString();
    list.get(i).put("HK_AMT", bValue);

     

    展开全文
  • BigDecimal

    2019-04-09 17:49:09
    Java中BigDecimal一、简介和分类二、除法三、.setScale()四、Java中...如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负 scale 次幂。因此,BigDecimal 表示的数值是 (unscal...

    一、简介和分类

    BigDecimal 由任意精度的整数非标度值 和 32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负 scale 次幂。因此,BigDecimal 表示的数值是 (unscaledValue × 10-scale)。

    可以处理任意长度的浮点数运算。

    BigDecimal add(BigDecimal val) //BigDecimal 加法

    BigDecimal subtract (BigDecimal val) //BigDecimal 减法

    BigDecimal multiply (BigDecimal val) //BigDecimal 乘法

    BigDecimal divide (BigDecimal val,RoundingMode mode) 除法

    具体使用 计算:

    加: a.add(b);

    减: a.subtract(b);

    乘: a.multiply(b);

    除: a.divide(b,2);//2为精度取值
      
    原文链接https://blog.csdn.net/zhangyinhu8689/article/details/84221149

    二、除法

    报错: java.lang.ArithmeticException: Rounding necessary
    原因: 精度丢失问题
    在这里插入图片描述
    举例子:
    如下代码就是导致问题的原因:

    System.out.println(new BigDecimal(“1225.120”).setScale(2));//不会出错
    System.out.println(new BigDecimal(“1225.121”).setScale(2));//出错原因精度丢失问题,要指定舍入模式即可
    以下两种方式解决了精度丢失的问题:
    new BigDecimal(“1225.125”).setScale(2, RoundingMode.HALF_UP)
    new BigDecimal(“1225.121”).setScale(2,BigDecimal.ROUND_HALF_UP)

    原文链接https://blog.csdn.net/qq496013218/article/details/70792655

    三、.setScale()

    BigDecimal.setScale()方法用于格式化小数点

    setScale(1)表示保留一位小数,默认用四舍五入方式
    setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3
    setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4
    setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4
    setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍

    原文链接https://blog.csdn.net/ahwr24/article/details/7048724

    四、Java中BigDecimal的8种舍入模式

    1、ROUND_UP

    舍入远离零的舍入模式。

    在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。

    注意,此舍入模式始终不会减少计算值的大小。

    2、ROUND_DOWN

    接近零的舍入模式。

    在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。

    注意,此舍入模式始终不会增加计算值的大小。

    3、ROUND_CEILING

    接近正无穷大的舍入模式。

    如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;

    如果为负,则舍入行为与 ROUND_DOWN 相同。

    注意,此舍入模式始终不会减少计算值。

    4、ROUND_FLOOR

    接近负无穷大的舍入模式。

    如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;

    如果为负,则舍入行为与 ROUND_UP 相同。

    注意,此舍入模式始终不会增加计算值。

    5、ROUND_HALF_UP

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

    如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。

    注意,这是我们大多数人在小学时就学过的舍入模式(四舍五入)。

    6、ROUND_HALF_DOWN

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

    如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。

    7、ROUND_HALF_EVEN

    向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

    如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;

    如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。

    注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。

    此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。

    如果前一位为奇数,则入位,否则舍去。

    以下例子为保留小数点1位,那么这种舍入方式下的结果。

    1.15>1.2 1.25>1.2

    8、ROUND_UNNECESSARY

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

    如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。

    不同舍入模式下的舍入操作汇总

    根据给定的舍入模式将输入数字舍入为一位数的结果
    输入数字UPDOWNCEILINGFLOORHALF_UPHALF_DOWNHALF_EVENUNNECESSARY
    5.56565656抛出 ArithmeticException
    2.53232322抛出 ArithmeticException
    1.62121222抛出 ArithmeticException
    1.12121111抛出 ArithmeticException
    1.011111111
    -1.0-1-1-1-1-1-1-1-1
    -1.1-2-1-1-2-1-1-1抛出 ArithmeticException
    -1.6-2-1-1-2-2-2-2抛出 ArithmeticException
    -2.5-3-2-2-3-3-2-2抛出 ArithmeticException
    -5.5-6-5-5-6-6-5-6抛出 ArithmeticException

    原文链接http://www.bdqn.cn/news/201311/11834.shtml

    展开全文
  • BigDecimal 与其他类型转换

    千次阅读 2017-12-07 10:11:31
    至此,已经可以得到一个正确的元分的代码,但是这里的s.length()终归不让人感觉舒服,接下来,我们探索BigDecimal原理,尝试用更优雅的方法解决这个问题。 BigDecimal,不可变的、任意精度的有符号十进制数。 ...

    最近查看rebate数据时,发现一个bug,主要现象是,当扣款支付宝的账号款项时,返回的是数字的金额为元,而数据库把金额存储为分,这中间要做元与分的转化,这个转化规则很简单,就是*100的,所以一开始代码很简单,如下。

    [java]  view plain  copy
    1. Float f =  Float.valueOf(s);  
    2. f =f*100;  
    3. Long result = f.longValue();  
    s=”9.86” 时,杯具出现了, result 的结果为 985 而不是 986 float 的精度损失导致 float(985.99994) 转化为整形时,丢掉小数部分成为 985 ,简单的方法,我们可以提高精度使用双精度的 double 类型,提高精度,比如
    [java]  view plain  copy
    1. Double d =  Double.valueOf(s);  
    2. d = d*100;  
    3. Long result = d.longValue();  
    当s=”9.86”时,确实能够得到正确结果,但是当s=”1219.86”时,这时候由于精度问题导致最终的result为121985为不是121986。当时以为使用double解决的问题,其实隐藏更隐蔽的bug。
    针对这样的问题,如果使用C/C++语言,那么通用解决方案可以这样。

    [java]  view plain  copy
    1. Double d =  Double.valueOf(s);  
    2. d = d*100+0.5;// 注意这里,我们使用的是+0.5的形式。  
    3. Long result = d.longValue();  
    但是,我们使用的java语言,java应该有更优雅的解决方案,那就是BigDecimal。

    使用BigDecimal的解决方案成这个样子

    [java]  view plain  copy
    1. Double dd= Double.valueOf(s);  
    2. BigDecimal bigD = new BigDecimal(dd);  
    3. bigD = bigD.multiply(new BigDecimal(100));  
    4. Long result = bigD.longValue();  
    狂晕,输出结果是985为不是986,打印bigD 
    [java]  view plain  copy
    1. System.out.println(bigD.toString());  
    输出如下
    [java]  view plain  copy
    1. 985.9999999999999431565811391919851303100585937500  
    不会再加上一个BigDecimal(0.5)吧。我相信在使用过BigDecimal过程中,肯定有那里不对的地方, multiply 方法中可以传入精度,那就构造 MathContext 对象,修改如下

    [java]  view plain  copy
    1. Double dd= Double.valueOf(s);  
    2. BigDecimal bigD = new BigDecimal(dd);  
    3. MathContextmc = new MathContext(4,RoundingMode.HALF_UP);  
    4. //4表示取四位有效数字,RoundingMode.HALF_UP表示四舍五入  
    5. bigD= bigD.multiply(new BigDecimal(100),mc);  
    6. Long result = bigD.longValue();  
    最后结果输出为986,貌似已经找到完成解决方案,其实不然,注意到 MathContext 中的4了嘛?这是因为我们保留4位有效数字,假如我们输入的数字是大于4的,比如1219.86,最终输出结果是122000,这是因为1219.86保留4位有效数字时,第四位的9四舍五入,除去精确位补零,所以最终结果成了122000。问题就成了,我们必须知道元变分后的最终有效位数,”9.86”,有效位数是4,”19.86”有效位数是5,把字符串s的长度传过去就可以了,那么代码如下
    [java]  view plain  copy
    1. Double dd =Double.valueOf(s);  
    2. BigDecimalbigD = new BigDecimal(dd);  
    3. MathContextmc = new MathContext(s.length(),RoundingMode.HALF_UP);  
    4. //4表示取四位有效数字,RoundingMode.HALF_UP表示四舍五入  
    5. bigD= bigD.multiply(new BigDecimal(100),mc);  
    6. Long result = bigD.longValue();  
    至此,已经可以得到一个正确的元转分的代码,但是这里的s.length()终归不让人感觉舒服,接下来,我们探索BigDecimal原理,尝试用更优雅的方法解决这个问题。
    BigDecimal,不可变的、任意精度的有符号十进制数。 BigDecimal  由任意精度的整数 非标度值  和 32 位的整数 标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负 scale 次幂。因此, BigDecimal  表示的数值是  (unscaledValue × 10-scale) 。我们知道BigDecimal有三个主要的构造函数

    1

    public BigDecimal(double val)

    将double表示形式转换为BigDecimal

    2

    public BigDecimal(int val)

    将int表示形式转换为BigDecimal

    3

    public BigDecimal(String val)

    将字符串表示形式转换为BigDecimal

    通过这三个构造函数,可以把double类型,int类型,String类型构造为BigDecimal对象,在BigDecimal对象内通过BigIntegerintVal存储传递对象数字部分,通过int scale;记录小数点位数,通过int precision;记录有效位数(默认为0)。
    BigDecimal的加减乘除就成了BigInteger与BigInteger之间的加减乘除,浮点数的计算也转化为整形的计算,可以大大提供性能,并且通过BigInteger可以保存大数字,从而实现真正大十进制的计算,在整个计算过程中,还涉及scale的判断和precision判断从而确定最终输出结果。
    我们先看一个例子

    [java]  view plain  copy
    1. BigDecimal d1 = new BigDecimal(0.6);  
    2. BigDecimal d2 = new BigDecimal(0.4);  
    3. BigDecimal d3 = d1.divide(d2);  
    4. System.out.println(d3);  
    大家猜一下,以上输出结果是? 再接着看下面的代码
    [java]  view plain  copy
    1. BigDecimal d1 = new BigDecimal(“0.6”);  
    2. BigDecimal d2 = new BigDecimal(“0.4”);  
    3. BigDecimal d3 = d1.divide(d2);  
    4. System.out.println(d3);  
    看似相似的代码,其结果完全不同,第一个例子中,抛出异常。第二个例子中,输出打印结果为 1.5 。造成这种差异的主要原因是第一个例子中的创建 BigDecimal 时, 0.6 0.4 是浮动类型的,浮点型放入 BigDecimal 内,其存储值为
    [java]  view plain  copy
    1. 0.59999999999999997779553950749686919152736663818359375  
    2. 0.40000000000000002220446049250313080847263336181640625  
    这两个浮点数相除时,由于除不尽,而又没有设置精度和保留小数点位数,导致抛出异常。而第二个例子中 0.6 0.4 是字符串类型,由于 BigDecimal 存储特性,通过 BigInteger记录BigDecimal的值,所以,0.6和0.4可以非常正确的记录为
    [java]  view plain  copy
    1. 0.6  
    2. 0.4  
    两者相除得出1.5来。
    对于第一个例子,如果我们想得到正确结果,可以这样来
    [java]  view plain  copy
    1. BigDecimal d1 = new BigDecimal(0.6);  
    2. BigDecimal d2 = new BigDecimal(0.4);  
    3. BigDecimal d3 = d1.divide(d2, 1, BigDecimal.ROUND_HALF_UP);  
    现在看我们留下的那个问题,使用更优雅的方式解决元转化为分的方式,上一个问题中,我们通过传递s.length()从而获得精度,如果之前的s是double类型的,那边这样的方式就会有问题,通过上面的例子,我们可以调整为一下的通用方式
    [java]  view plain  copy
    1. Double dd= Double.valueOf(s);  
    2. BigDecimal bigD = new BigDecimal(dd);  
    3. bigD = bigD.multiply(newBigDecimal(100)). divide(11, BigDecimal.ROUND_HALF_UP);  
    4. Long result = bigD.longValue();  
    我们通过/1,然后设置保留小数点方式,以及设置数字保留模式,从而得到两个数乘积的小数部分。还有以下模式

    枚举常量摘要  
    ROUND_CEILING   
              向正无限大方向舍入的舍入模式。 
    ROUND_DOWN   
              向零方向舍入的舍入模式。 
    ROUND_FLOOR   
              向负无限大方向舍入的舍入模式。 
    ROUND_HALF_DOWN   
              向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。 
    ROUND_HALF_EVEN   
              向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
    ROUND_HALF_UP   
              向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。 
    ROUND_UNNECESSARY   
              用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。(默认模式) 
    ROUND_UP   
              远离零方向舍入的舍入模式。

    总结:
    1:尽量避免传递double类型,有可能话,尽量使用intString类型。
    2:做乘除计算时,一定要设置精度和保留小数点位数。
    3BigDecimal计算时,单独放到try catch内。

    展开全文
  • BigDecimal 简介

    2018-06-29 12:28:56
    如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负 scale 次幂。因此,BigDecimal 表示的数值是 (unscaledValue × 10-scale)。 可以处理任意长度的浮点数运算。 BigDecimal ...
  • BigDecimal

    2019-05-04 00:03:20
    如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负 scale 次幂。因此,BigDecimal 表示的数值是 (unscaledValue × 10-scale)。 概述: 由于在运算的时候,float类型和double...
  • BigDecimal总结

    千次阅读 2015-06-04 17:50:30
    BigDecimal
  • BigDecimal运算

    2018-08-03 15:52:00
    如果为零或正数,则刻度是小数点右侧的位数。 如果是负数,则数字的非标定值乘以10,以达到等级的否定的幂。 因此,BigDecimal所代表的BigDecimal值为(unscaledValue × 10-scale) 。 创建BigDecimal对象: ...
  • BigDecimal 解析

    2019-09-03 12:26:31
    叙述 大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。比如:货币 ...BigDecimal BigDecimal(double d); //不允许使用,精度不能保证 BigDecimal BigDecimal(String s); ...
  • BigDecimal bigDecimal = new BigDecimal(“2.125456”).setScale(2, BigDecimal.ROUND_DOWN); System.out.println(bigDecimal ); //结果:2.12 ROUND_UP(直接对指定位数后的内容做进一位处理) BigDecimal b...
  • BigDecimal 用法

    千次阅读 2018-08-07 20:48:51
    /** * 除法,取digit位小数,四舍五入 */ public static BigDecimal getDivideData (String str1, String str2, int ... BigDecimal a = new BigDecimal(str1); BigDecimal b = new BigDecimal(str2); return...
  • BigDecimal 的 toString() 方法将会把 BigDecimal 通过字符串的方式输出。这个方法将会在必要的时候使用指数进行输出。 具体的转换步骤是按照下面的步骤进行转换的: BigDecimal的非标度值的绝对值用字符’0’到’...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,256
精华内容 1,302
关键字:

bigdecimal正数转负数