我是靠谱客的博主 矮小冥王星,最近开发中收集的这篇文章主要介绍double浮点数计算的一些问题,以及bigDecimal的使用,和DecimalFormat的对比,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 考考你
      • System.out.println(1/5); 输出结果是多少?
      • System.out.println(null-0.0); 输出结果是多少?
    • double部分
      • double 计算如果一个空null,会报错吗?
      • double类型将分母置1
    • BigDecimal部分
      • 为什么要用BigDecimal
      • 格式化小数位数
      • BigDecimal的非空非0判断
    • DecimalFormat的例子
      • DecimalFormat为什么不能格式化字符串
    • 答案部分
    • 其他
      • new BigDecimal(null)报空指针异常
      • 入参中如何判断BigDecimal是否为空
      • BeanUtils属性复制不能将Double复制到BigDecimal

考考你

先来几道简单的题目。

System.out.println(1/5); 输出结果是多少?

题目1答案

System.out.println(null-0.0); 输出结果是多少?

题目2答案

double部分

double 计算如果一个空null,会报错吗?

Double d1=0.0;
Double d2=1.0;
Double result=d1-d2;

实测报错。 所以double类型计算之前,要进行非空校验。
这里要注意的是, 如果不set null,初始化的值是0.0,是不报错的。

double类型将分母置1

因为如果是分母是0.0,那么结果会为Infinity。
所以最好置为其他值。

Double d1=0.0;
Double d2=1.0;
Double result=d1/(d2!=0?d2:1.0);

BigDecimal部分

为什么要用BigDecimal

java中浮点数计算不是很精准,BigDecimal可以很好的解决这个题目。

格式化小数位数

BigDecimal对这个的支持还是很好的。 例如,设置为6位小数。

private BigDecimal amount;

this.amount=new BigDecimal(0.0).setScale(6,BigDecimal.ROUND_HALF_UP);

BigDecimal的非空非0判断

实际当中,有很多需要判断BidDecimal不为空且不为0。
那么怎么写呢?

错误代码:

if(null!=amount && !amount.equals(new BigDecimal(0))){
}

这段代码乍看没问题,甚至测试的时候也没问题,但是实际是有问题的。
为什么呢,因为equals比的时候会考虑到scale。 如果传入的参数设置了scale,结果可能会不一致。

举例如下:

System.out.println(new BigDecimal(0).equals(new BigDecimal(0.0).setScale(2,BigDecimal.ROUND_HALF_UP))); // 返回 false

所以,应该用compareTo来比较。正确代码:

// bigDecimal不为空且不为0
public static boolean isNotNullAndNotZero(BigDecimal bigDecimal){
    boolean flag=false;
    if(null!=bigDecimal && 0!=new BigDecimal(0).compareTo(bigDecimal)){
        flag=true;
    }
    return flag;
}

DecimalFormat的例子

使用例子:

DecimalFormat format = new DecimalFormat("#.00");
format.format(1); 
format.format(1.00);
format.format(new Double(2));
format.format(new BigDecimal(0.01));

报错例子:

DecimalFormat format = new DecimalFormat("#.00");
format.format("1001.00");  // 会报错

报错提示:
java.lang.IllegalArgumentException: Cannot format given Object as a Number
这是最常见的一个错误,也就是说DecimalFormat格式化字符串会报错。这是为什么呢?

DecimalFormat为什么不能格式化字符串

我们知道传递字符串会报错,不传字符串就是了。
再进一步,传字符串为什么会报错? 又有哪些类型可以传递呢?
专门跟了下代码:

@Override
public final StringBuffer format(Object number,
                                 StringBuffer toAppendTo,
                                 FieldPosition pos) {
    if (number instanceof Long || number instanceof Integer ||
               number instanceof Short || number instanceof Byte ||
               number instanceof AtomicInteger ||
               number instanceof AtomicLong ||
               (number instanceof BigInteger &&
                ((BigInteger)number).bitLength () < 64)) {
        return format(((Number)number).longValue(), toAppendTo, pos);
    } else if (number instanceof BigDecimal) {
        return format((BigDecimal)number, toAppendTo, pos);
    } else if (number instanceof BigInteger) {
        return format((BigInteger)number, toAppendTo, pos);
    } else if (number instanceof Number) {
        return format(((Number)number).doubleValue(), toAppendTo, pos);
    } else {
        throw new IllegalArgumentException("Cannot format given Object as a Number");
    }
}

很明显,常规的数字类型,Integer,Double,Number等类型,以及BigDecimal都是可以的。

答案部分

题目1答案

题目1:System.out.println(1/5); 输出结果是多少?

不是预期的0.2哦,而是0。
因为1/5这种写法会认为是整数除法,会忽略小数位。所以结果是0。

如果要返回0.2,以下2种都可以。

加上.0表示浮点数,会进行浮点计算:
1.0/5
加上d表示是double浮点类型,会进行浮点计算:
1d/5

题目2答案:

题目2:System.out.println(null-0.0); 输出结果是多少?

是输出0吗?
不对,会报错。 因为浮点数计算的时候不能为null。

其他

new BigDecimal(null)报空指针异常

接口查询出的Double对象,有可能为空。
这样 new BigDecimal() 的时候会报空指针。

所以new BigDecimal()对象的时候,最好判断下空。
或者用三目运算符:

new BigDecimal(amount!=null?amount:0.0);

入参中如何判断BigDecimal是否为空

用StringUtils判断即可:

BigDecimal amount = model.getAmount();
if(StringUtils.isEmpty(amountTax)){
    return "金额不能为空";
}

BeanUtils属性复制不能将Double复制到BigDecimal

描述:
入参有值,复制后却收不到,后来发现是Double类型不能直接复制到BigDecimal。

最后

以上就是矮小冥王星为你收集整理的double浮点数计算的一些问题,以及bigDecimal的使用,和DecimalFormat的对比的全部内容,希望文章能够帮你解决double浮点数计算的一些问题,以及bigDecimal的使用,和DecimalFormat的对比所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部