最近做处理金额的业务比较多,所以最近遇到两个关于数字的坑,记下来以便以后不犯这种错误
1.0.57*100=?
问题代码: 相信大多数人阅读上面这段代码都认为结果是57,但是运行结果却是56 问题原因: 计算机存储数字采用的是二进制,0.57在计算机中存储的二进制再转化成十进制的值是0.56999…,再乘100取整就是56。 解决办法: 先转化成String类型再用BigDecimal进行运算。BigDecimal中有记录有效数字长度的precision、记录小数点位置的scale以及有效数字intCompact。如果不转化成String,BigDecimal不会记录小数位和长度这些信息,计算时还是会像第一次那样进行数字的普通计算2.FastJson处理double类型
问题代码: 其实结果倒是没错,但是问题在于一个使用科学技术法一个没有使用,这如果传给前端,客户肯定会反馈数字风格不一致的问题 问题原因: 使用fastjson将json字符串反序列化成Map对象时,如果属性值是double类型,那么fastjson会默认当成BigDecimal来处理,相当于fastjson会调用new BigDecimal(String.valueOf(d1).toCharArray(), 0, String.valueOf(d1).length(), MathContext.UNLIMITED);来创建一个BigDecimal对象,然后println方法会默认调用对象的toString方法,BigDecimal的toString中会判断上文中提到的scale属性,如果scale属性是0(小数位的长度为0)则直接调用Long.toString(val),如果scale属性小于0(小数位的长度为负数,也就是说数字是整数,并且最后一位或者最后几位是0,最后面有几个0,scale就是负几)那么在toString方法中就会以科学记数的法表示 解决办法: 使用toPlainString替代toString,toPlainString会使用数字的默认展示方式,而不是科学记数法。 注:本人使用的是1.2.83版本的fastjson,这版本的是将double转化成BigDecimal。 但是在最新版的fastjson中,是没有转化,double类型还是double类型。 所以以上代码就会变成这样:如果想直接输出普通的数字,可以直接使用new BigDecimal(double val);这个构造方法构造出的BigDecimal对象,直接使用toString就是普通的数字
标签:fastjson,scale,数字,double,toString,迷惑,行为,BigDecimal From: https://www.cnblogs.com/lrxsznbe/p/17607291.html