最近在做支付相关模块的业务,数据库字段却使用的是double类型,其实也行,只要计算不在sql语句中进行,也是没有问题的。

预先的类属性设置的是Double类型,自己算的时候发现小数相加会出现损失精度的情况

如下情形

    @Testpublic void testDouble(){Double [] arr = {39.9d,50d,198d,39.9d};Double verify = 0d;for (Double aDouble : arr) {verify += aDouble ;}System.out.println(verify);}

输出的结果是:327.79999999999995  理应为:328

待着疑惑试了下js

一看是一个效果,精度都会缺失。百度了下,解释如下

产生原因:
    计算机并不能识别除了二进制数据以外的任何数据,无论我们使用何种编程语言,在何种编译环境下工作,都要先把源程序翻译成二进制的机器码后才能被计算机识别。
    而在存储浮点型数据时,会分为三部分进行存储:
  1. 符号位(Sign): 0代表正,1代表为负
  2. 指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储
  3. 尾数部分(Mantissa):尾数部分
    其中前两位分别为实数符号位和指数符号位,于是存储结构实际为如下:
                    31                  30            29----23        22----0         

               实数符号位    指数符号位    指数位      有效数位

但是,在将十进制浮点数转换为二进制浮点数时,小数的二进制有时也是不可能精确的,就如同十进制不能准确表示1/3,二进制也无法准确表示1/10,而double类型存储尾数部分最多只能存储52位,于是,计算机在存储该浮点型数据时,便出现了精度丢失。

  例如,11.9的内存存储大约为:1011. 1110011001100110011001100...

而在进行浮点类数据计算的时候,浮点参与计算,会左移或右移n位,直到小数点移动到第一个有效数字的右边。于是11.9在转化为二进制后 小数点左移3位,就得到1. 011 11100110011001100110(精度丢失2)

于是最终浮点型运算出现了精度丢失误差。

解决方式,java中可以使用 BigDecimal 来解决

    @Testpublic void test3(){System.out.println(0.11+2001299.32);//非精确的输出BigDecimal bigDecimal1 = new BigDecimal(Double.toString(0.11));BigDecimal bigDecimal2 = new BigDecimal(Double.toString(2001299.32));System.out.println(bigDecimal1.add(bigDecimal2));//精确的输出}

这种方式可以解决,并且很完美,但是还有一种方式比较容易些,毕竟是金额,小数位只有两位,可以先将其扩大100倍,再进行计算,计算完毕之后再除100,也可以解决(这么不要脸的方式也只有我这么low的程序员使用了),惭愧,出错了。

在计算的过程总遇到double转int的情况,总结了下实现的方式

    Double d = 1.7d;@Testpublic void test1(){// 这样会报错,因为double转换为字符串之后有.
        System.out.println(Integer.parseInt(d.toString()));}@Testpublic void test2_1(){// double 类型可以直接转为int类型double dd = 1.1;int ddd = (int)dd;System.out.println(ddd);}@Testpublic void test2_2(){// 可以通过强转进行转换,Double是包装类,不能直接进行强转,可以拆箱之后再次强转。int aa = (int)(Double.parseDouble(d.toString()));System.out.println(aa);}@Testpublic void test3(){// 这种方式最为简单
        System.out.println(d.intValue());}@Testpublic void test4(){DecimalFormat format1 = new DecimalFormat("#");String s = format1.format(d);System.out.println(s);}@Testpublic void test5(){DecimalFormat format1 = new DecimalFormat("#.#");String s = format1.format(1.35);System.out.println(s);}@Testpublic void test6(){DecimalFormat format1 = new DecimalFormat("0.000");String s = format1.format(1.35);System.out.println(s);}

DecimalFormat 要四舍五入需要加上 setRoundingMode(RoundingMode.HALF_UP); 网上是这么说的,但是自己测试默认就会四舍五入

特殊字符说明
“0” 指定位置不存在数字则显示为0 123.123 ->0000.0000 ->0123.1230
“#” 指定位置不存在数字则不显示 123.123 -> ####.#### ->123.123
“.” 小数点
“%” 会将结果数字乘以100 后面再加上% 123.123 ->#.00->1.3212%

嗯,就这么个坑了。

转载于:https://www.cnblogs.com/chywx/p/10456651.html

double转换为int以及浮点型相加损失精度问题相关推荐

  1. Java黑皮书课后题第4章:*4.26(金融应用:货币单位)重写程序清单2-10,解决将float型值转换为int型值时可能会造成精度损失的问题。读取的输入值是一个字符串,比如“11.56“

    *4.26(金融应用:货币单位)重写程序清单2-10,解决将float型值转换为int型值时可能会造成精度损失的问题.读取的输入值是一个字符串,比如"11.56" 题目 题目概述 ...

  2. 用于将类型从double转换为int的C#程序

    Given a double type of variable, we have to convert it into an integer in C#. 给定双重类型的变量,我们必须在C#中将其转换 ...

  3. 如何在Java中将double转换为int?

    在本文中,我们将看到如何将double转换为int. 在Java编程中,您将有一个double原语值(例如82.14),但是要执行进一步的操作,您需要一个int值(例如82),所以让我们看看如何在Ja ...

  4. double转换成int java,Java将double转换为int

    本文概述 我们可以使用类型转换在Java中将double转换为int.要将double数据类型转换为int, 我们需要执行类型转换. Java中的类型转换通过类型转换运算符(数据类型)执行. 在这里, ...

  5. javadouble转int四舍五入_如何通过舍入将Java中的double转换为int?

    要将double转换为int并将其四舍五入为最接近的整数(即与典型的(int)(1.8)and 不同(int)(1.2),它们都将"向下舍入"为0并返回1),只需在上加上0.5do ...

  6. Java之使用 Double.IntValue()将double转换为int

    double值转换为Double包装器类,然后使用该Double.IntValue()方法获取int值. double doubleValue = 1.10; //double值转换为Double包装 ...

  7. java中将int转换float_在java中将float和double转换为int时有什么区别?

    我用这些语句来测试 float f=4.35f; int i=(int)(f*100); System.out.println(i); double d=4.35; i=(int)(d*100); S ...

  8. Java黑皮书课后题第2章:*2.22(金融应用:货币单位)改写程序清单2-10,解决将double转int可能会造成精度损失问题。以整数值作为输入,其最后两位代表的是美分币值

    *2.22(金融应用:货币单位)改写程序清单2-10,解决将double转int可能会造成精度损失问题.以整数值作为输入,其最后两位代表的是美分币值 题目 题目概述 举例 程序清单2-10 修改思路 ...

  9. double operator[](int i)_java中double类型精度丢失问题及解决方法

    原文链接:https://blog.csdn.net/yacolspace/article/details/78287394 double类型数据加减操作精度丢失问题 今天在项目中用到double类型 ...

最新文章

  1. 连发10篇SCI!徐州二本学霸全奖直博香港城大引热议
  2. DNS-sly:利用网络复杂性躲避审查
  3. makefile 文件模板
  4. 京东java社招面试6_2020最新京东java面试题分享,京东社招
  5. 第二十四期:管理 | 成功领导远程IT团队的7个技巧
  6. mysql 默认page大小_Innodb优化之修改页大小
  7. java this.name= name_thread(this, ThreadName)对于Java中这个语句,this是什么?
  8. MongoDB中MapReduce介绍与使用
  9. java一个引用多大_为什么Java 8为方法引用引入了一个新的“::”运算符?
  10. 0514JS练习:函数
  11. leetcode [53]最大子序和/Maximum Subarray C++ 暴力解法和贪心解法
  12. php什么时候面向对象,php什么时候使用面向对象
  13. 编程语言为什么不能用中文
  14. 黑苹果教程(一)VM装黑苹果
  15. workerman php使用,workerman怎么用
  16. 《欧洲文学名著导读》——读书笔记
  17. 【蓝桥杯】入门训练 Fibonacci数列
  18. 38.DevOps之基于Jenkins实现的CI与CD
  19. 10、STL实用技术专题
  20. Python:tkinter Canvas 删除/清理元素方法

热门文章

  1. 远程服务器的url怎么配置文件,Linux常用命令(5)--SSH访问远程服务器、SCP服务器间文件拷贝...
  2. 11467人力资源统计学在计算机,2013年至2017年自考11467《人力资源统计学》真题及答案.pdf...
  3. html 页面宽度和背景颜色,CSS:设置背景颜色为窗口宽度的50%
  4. android 添加附件功能,Android实现带附件的邮件发送功能
  5. lingo calcinit
  6. Matlab学习笔记——图形标注
  7. 最常用的10个Matlab快捷键,助你编程更高效
  8. 《模拟信息转换器(AIC)的实现技术研究》读书笔记
  9. webstorm中配置vue代码片段
  10. DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描...