概述
文章目录
- 考考你
- 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的对比所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复