当前位置:网站首页>double类型精度丢失问题以及解决方法
double类型精度丢失问题以及解决方法
2022-07-23 09:58:00 【ErwinNakajima】
1、double类型精度丢失问题:
(1)加法运算。
public static void main(String[] args) {
double number1 = 1;
double number2 = 20.2;
double number3 = 300.03;
double result = number1 + number2 + number3;
System.out.println("使用double运算结果: "+result);
}打印结果如下:
使用double运算结果: 321.22999999999996。。。
(2)乘法运算。
public static void main(String[] args) {
double a = 152.70;
System.out.println(a);
System.out.println(a * 100);//15280.000000000002
System.out.println(Math.round(a * 100));//还凑合
double b = 152.70;
System.out.println(b);
System.out.println(b * 100);//15269.999999999998
System.out.println((int)(b * 100));//15269 错误!!!不是想要的
}然后把15280.000000000002 - 15280 = 1.8189894035458565E-12这个结果返回给了前端,
前端拿去和0比较, 结果就炸了
原因:就是double的精度问题, 单个double数可能就有损失精度,,多个double数运算(减法和乘法都输入加法)可能导致损失的精度更多。。。
(3)减法运算。
double d1 = 2.11;
double d2 = 2.10;
System.out.println( d1 - d2);口算结果是0.01。可是用程序执行出来的结果却出乎意料,执行结果为0.009999999999999787。
问题解决
转换为BigDecimal对象之后再进行加减乘除操作,这样精度就不会出现问题了。这也是为什么有关金钱数据存储都使用BigDecimal。
处理double类型数据的加、减、乘、除运算时,使用如下方法:
package com.phone.common_library.manager;
import java.math.BigDecimal;
public class BigDecimalManager {
/**
* 加法运算
* @param m1
* @param m2
* @return 不加doubleValue()则, 返回BigDecimal对象
*/
public static double additionDouble(double m1, double m2) {
BigDecimal p1 = new BigDecimal(Double.toString(m1));
BigDecimal p2 = new BigDecimal(Double.toString(m2));
return p1.add(p2).doubleValue();
}
/**
* 减法运算
* @param m1
* @param m2
* @return 不加doubleValue()则, 返回BigDecimal对象
*/
public static double subtractionDouble(double m1, double m2) {
BigDecimal p1 = new BigDecimal(Double.toString(m1));
BigDecimal p2 = new BigDecimal(Double.toString(m2));
return p1.subtract(p2).doubleValue();
}
/**
* 乘法运算
* @param m1
* @param m2
* @return 不加doubleValue()则, 返回BigDecimal对象
*/
public static double multiplicationDouble(double m1, double m2) {
BigDecimal p1 = new BigDecimal(Double.toString(m1));
BigDecimal p2 = new BigDecimal(Double.toString(m2));
return p1.multiply(p2).doubleValue();
}
/**
* 除法运算
* @param m1
* @param m2
* @param scale
* @return 不加doubleValue()则, 返回BigDecimal对象
*/
public static double divisionDouble(double m1, double m2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("Parameter error");
}
BigDecimal p1 = new BigDecimal(Double.toString(m1));
BigDecimal p2 = new BigDecimal(Double.toString(m2));
return p1.divide(p2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
}
·测试、验证问题是否解决:
public static void main(String[] args) {
double result1 = additionDouble(1, 20.2);
double result2 = additionDouble(result1, 300.03);
System.out.println("使用BigDecimal运算结果:" + result2);
}结果如下:
使用BigDecimal运算结果:321.23
完美解决了double类型数据加减操作时精度丢失的问题。
如对此有疑问,请联系qq1164688204。
推荐Android开源项目
项目功能介绍:RxJava2和Retrofit2项目,添加自动管理token功能,添加RxJava2生命周期管理,使用App架构设计是MVP模式和MVVM模式,同时使用组件化,部分代码使用Kotlin,此项目持续维护中。
项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2
边栏推荐
猜你喜欢

Subsequence --- edit distance

Live classroom system 01 database table design

C language project practice: 24 point game calculator (based on knowledge points such as structure, pointer, function, array, loop, etc.)

Opencv calculation outsourcing rectangle
![[array & String & Macro exercise]](/img/44/26debc1ee958277935e73a75d894d4.png)
[array & String & Macro exercise]

什么是Per-Title编码?

Prometheus入门使用(三)

Live classroom system 03 supplement model class and entity

【无标题】测试【无标题】测试

turbo编译码误码率性能matlab仿真
随机推荐
Program design of dot matrix Chinese character display of basic 51 single chip microcomputer
Russia hopes to effectively implement the "package" agreement on the export of agricultural products
Qt|模仿文字浮动字母
QT document reading notes audio example analysis
Supervisor installation and use
c语言:深度刨析const关键字
21 - 二叉树的垂直遍历
The best time to buy and sell stocks
【无标题】
[software test] redis abnormal test encountered in disk-to-disk work
MySQL 常用命令
Leetcode: 17. letter combination of phone number
基于matlab的BOC调制信号捕获仿真
【解决异常】Flink上传jar包至集群环境运行报未序列化异常
【机器学习基础】无监督学习(5)——生成模型
581. Shortest unordered continuous subarray
Live classroom system 03 model class and entity
如何实现多个传感器与西门子PLC之间485无线通讯?
运维高级作业03
【启发式分治】启发式合并的逆思想