ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

decimal相关知识

2021-12-29 18:35:39  阅读:186  来源: 互联网

标签:scale return BigDecimal decimal 知识 param v1 v2 相关


一、初始化

decimal 的初始化方式有四种

1、new decimal(int);

2、new decimal(long);

3、new decimal(dubbo);会有精度丢失的风险;使用BigDecimal d= BigDecimal.valueOf(dubbo);初始化dubbo

4、new decimal(String);小数最好使用字符初始化

二、计算方式

//加法
BigDecimal r1= v1.add(v2);
//减法
BigDecimal r2= v1.subtract(v2);
//乘法
BigDecimal r3= v1.multiply(v2);
//除法
BigDecimal r4= v1.divide(v2);

三、为什么decimal中不能使用equal进行值比较,而是使用compareTo?

首先肯定是不会用==这种方式来使用哦,这个应该不用多说吧,BigDecimal属于对象,不是基本类型,不能用==来比较

  BigDecimal r1= new BigDecimal(10);
  BigDecimal r2 = new BigDecimal(10);
  System.out.println(r1.equals(r2));
  BigDecimal r3= new BigDecimal(10);
  BigDecimal r4= new BigDecimal(10.000);
  System.out.println(r3.equals(r4));
  BigDecimal r5= new BigDecimal("10");
  BigDecimal r6= new BigDecimal("10.000");
  System.out.println(r5.equals(r6));

以上代码输出结果:true  true  false

针对equal对比为什么r1与r2是ture的,r3与r4也是ture,r5与r6是false

在源码中有一段

 public class BigDecimal extends Number implements Comparable<BigDecimal> {

        private final BigInteger intVal;

        private final int scale; 

        private final transient long intCompact;

/**省略代码**/
public boolean equals(Object x) { if (!(x instanceof BigDecimal)) return false; BigDecimal xDec = (BigDecimal) x; if (x == this) return true; if (scale != xDec.scale) return false; long s = this.intCompact; long xs = xDec.intCompact; if (s != INFLATED) { if (xs == INFLATED) xs = compactValFor(xDec.intVal); return xs == s; } else if (xs != INFLATED) return xs == compactValFor(this.intVal); return this.inflated().equals(xDec.inflated()); }

 

equals不仅会比较数值,还会比较这个标度是否一样,也就是说equals会比较俩个参数,r5与r6的数值一样,但是scale不一样。而compareTo()这个方法只比较数值不比较scale标度。

然后我们来了解一下什么是scale:

如果scale为零或正值,则该值表示这个数字小数点右侧的位数。如果scale为负数,则该数字的真实值需要乘以10的该负数的绝对值的幂。例如,scale为-3,则这个数需要乘1000,即在末尾有3个0。

在BigDecimal有四种定义的类型,包括int、long、double、String四种,首先int和long类型都是整数,标度都是0。当类型是double的时候,new Bigdecimal(double)  => new BigDecimale(0.1),实际传入的是0.1000000000000000055511151231527827021181583404541015625,这个时候的标度就是55,也就是小数点的个数。

而对于 new bigDecimal(1.0)来说,实际上就是整数,也就是不存在后缀,所以和整数的标度大小是一样的使用r3与r4为ture

 

四、最后了解

了解一下实际上一个BigDecimal是通过一个"无标度值"和一个"标度"来表示一个数的。

而无标度值的表示比较复杂。当unscaled value超过阈值(默认为Long.MAX_VALUE)时采用intVal字段存储unscaled value,intCompact字段存储Long.MIN_VALUE,否则对unscaled value进行压缩存储到long型的intCompact字段用于后续计算,intVal为空。

里面有一个scale标度的比较,大概这就是为什么r5和r6的比较结果是false的原因了。

五、放一个decimal的工具类

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @create: 2019-04-18 18:19
 **/
public class BigDecimalUtil {

    public final static BigDecimal NEGATIVE_ONE = new BigDecimal(-1);

    public final static BigDecimal HUNDRED = new BigDecimal("100");

    public final static BigDecimal TEN_THOUSAND = new BigDecimal("10000");

    /**
     * 获取该数的相反数
     * @param number 需要转换的数字
     * @return java.math.BigDecimal
     * @date 2019/4/18 18:22
     */
    public static BigDecimal getOppositeNumber(BigDecimal number){
        return notNull(number).multiply(NEGATIVE_ONE);
    }

    /**
     * 两数相减
     * @param v1 被减数
     * @param v2 减数
     * @return java.math.BigDecimal
     * @date 2019/4/18 18:26
     */
    public static BigDecimal subtraction(BigDecimal v1, BigDecimal v2){
        return notNull(v1).subtract(notNull(v2));
    }

    /**
     * 两数相加
     * @param v1 加数1
     * @param v2 加数2
     * @return java.math.BigDecimal
     * @date 2019/4/18 18:26
     */
    public static BigDecimal addition(BigDecimal v1, BigDecimal v2){
        return notNull(v1).add(notNull(v2));
    }

    /**
     * 两数相除
     * @param v1 被除数
     * @param v2 除数
     * @param scale 保留小数位
     * @return java.math.BigDecimal
     * @date 2020/1/6 17:24
     */
    public static BigDecimal division(BigDecimal v1, BigDecimal v2, int scale){
        return division(v1, v2, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 两数相除
     * @param v1 被除数
     * @param v2 除数
     * @param scale 保留小数位
     * @param roundingMode 保留模式
     * @return java.math.BigDecimal
     * @date 2021/4/15 17:09
     */
    public static BigDecimal division(BigDecimal v1, BigDecimal v2, int scale, int roundingMode){
        return notNull(v1).divide(notNull(v2), scale, roundingMode);
    }

    /**
     * 如果除数为null或为0,则返回0
     * @param v1 被除数
     * @param v2 除数
     * @param scale 保留小数位
     * @return java.math.BigDecimal
     * @date 2020/3/2 11:56
     */
    public static BigDecimal divisionIgnoreZero(BigDecimal v1, BigDecimal v2, int scale){
        if (BigDecimalUtil.isEqualsZero(notNull(v2))){
            return BigDecimal.ZERO;
        }
        return BigDecimalUtil.division(v1, v2, scale);
    }

    /**
     * 两数相乘
     * @param v1 被乘数
     * @param v2 乘数
     * @param scale 保留小数位
     * @return java.math.BigDecimal
     * @date 2020/1/6 17:24
     */
    public static BigDecimal multiply(BigDecimal v1, BigDecimal v2, int scale){
        return notNull(v1).multiply(notNull(v2)).setScale(scale, RoundingMode.HALF_UP);
    }

    /**
     * 是否大于等于0
     * @param v 需要判断的值
     * @return boolean true:是;false:否
     * @date 2019/4/19 11:15
     */
    public static boolean isGreaterAndEqualsZero(BigDecimal v){
        int r = notNull(v).compareTo(BigDecimal.ZERO);
        return r > 0 || r == 0;
    }

    /**
     * v1是否大于等于v2
     * @param v1 左边的值
     * @param v2 右边的值
     * @return boolean true:是;false:否
     * @date 2019/4/19 11:15
     */
    public static boolean isGreaterAndEquals(BigDecimal v1, BigDecimal v2){
        int r = notNull(v1).compareTo(notNull(v2));
        return r > 0 || r == 0;
    }

    /**
     * v1是否大于v2
     * @param v1 左边的值
     * @param v2 右边的值
     * @return boolean true:是;false:否
     * @date 2021/4/22 14:53
     */
    public static boolean isGreater(BigDecimal v1, BigDecimal v2){
        int r = notNull(v1).compareTo(notNull(v2));
        return r > 0;
    }

    /**
     * v1是否等于0
     * @param v1 需比较的值
     * @return boolean true:是;false:否
     * @date 2019/4/19 17:12
     */
    public static boolean isEqualsZero(BigDecimal v1){
        int r = notNull(v1).compareTo(BigDecimal.ZERO);
        return r == 0;
    }

    /**
     * v1是否大于0
     * @param v1 需比较的值
     * @return boolean true:是;false:否
     * @date 2019/4/19 17:12
     */
    public static boolean isGreaterZero(BigDecimal v1){
        int r = notNull(v1).compareTo(BigDecimal.ZERO);
        return r > 0;
    }

    /**
     * v1是否等于v2
     * @param v1 左边的值
     * @param v2 右边的值
     * @return boolean true:是;false:否
     * @date 2019/6/10 16:52
     */
    public static boolean isEquals(BigDecimal v1, BigDecimal v2){
        int r = notNull(v1).compareTo(notNull(v2));
        return r == 0;
    }

    /**
     * 得到该数的正数
     * @param v 需要转换的数字
     * @return java.math.BigDecimal
     * @date 2019/6/12 14:41
     */
    public static BigDecimal getPositiveNumber(BigDecimal v){
        if (!isGreaterZero(v)){
            return getOppositeNumber(v);
        }
        return v;
    }

    /**
     * 得到该数的负数
     * @param v 需要转换的数字
     * @return java.math.BigDecimal
     * @date 2019/6/12 14:41
     */
    public static BigDecimal getNegativeNumber(BigDecimal v){
        if (isGreaterZero(v)){
            return getOppositeNumber(v);
        }
        return v;
    }

    /**
     * 获取非空的BigDecimal对象,为null则返回0
     * @param value 需要判断的值
     * @return java.math.BigDecimal 非空的BigDecimal对象
     * @date 2019/12/25 10:28
     */
    public static BigDecimal notNull(BigDecimal value){
        if (value == null) {
            return BigDecimal.ZERO;
        }
        return value;
    }

    /**
     * 获取两个数中比较小的值
     * @param v1 第一个值
     * @param v2 第二个值
     * @return java.math.BigDecimal 比较小的值
     * @date 2021/7/8 16:02
     */
    public static BigDecimal getLeast(BigDecimal v1, BigDecimal v2){
        return notNull(v1).compareTo(notNull(v2)) > 0? v2: v1;
    }

    /**
     * 获取两个数中比较大的值
     * @param v1 第一个值
     * @param v2 第二个值
     * @return java.math.BigDecimal 比较大的值
     * @date 2021-07-20 17:35
     */
    public static BigDecimal getBigger(BigDecimal v1, BigDecimal v2){
        return notNull(v1).compareTo(notNull(v2)) > 0? v1: v2;
    }

    /**
     * 获取百分比
     *
     * @param v     需要转换为百分比的值
     * @param scale 规模
     * @return {@link BigDecimal }
     * @date 2021-10-11 15:32:49
     */
    public static BigDecimal getPercentage(BigDecimal v, int scale){
        return BigDecimalUtil.multiply(v, HUNDRED, scale);
    }

    private BigDecimalUtil(){

    }
}

 

标签:scale,return,BigDecimal,decimal,知识,param,v1,v2,相关
来源: https://www.cnblogs.com/lqh969696/p/15746068.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有