吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5922|回复: 14
收起左侧

[Java 转载] Java的Double精度丢失解决方案

[复制链接]
尘缘丶 发表于 2017-5-7 01:55
本帖最后由 尘缘丶 于 2017-5-9 17:32 编辑

话题开始前,我想说一句无关的话题,也是鼓励像我一样的初学者
如果有什么简单易懂的源码或者成品软件,欢迎分享并分析给大家看,没准你发的一个帖子被其他人看到正好让别人收益呢,而且也能带动别人一起互动
我之前胆怯,不敢发帖,怕被论坛大佬嘲笑,但是我今天看见一位同学发的求助帖有我刚学过的东西,但是他的帖子没有分析,我就充当解说员吧,给大家分析一下

昨天下午看见一个论坛朋友3月20号发的一个求助帖,原帖地址:http://www.52pojie.cn/thread-591629-1-1.html
我这个刚学了1个月的Java弱鸡来分析下吧       分析之前先喊原帖楼主
@lmq2008
此楼主的源码:
[Java] 纯文本查看 复制代码
public class text{
        public static void main(String[] args){
        double b=3.0;
        double sum=30000;
        double i=0.1;
        double c=b+i;
        while(i<=0.3){        
                sum=sum+c*360;
                System.out.println(sum);i++;
                }
        }
}


我们可以看出,最起码的不算大错的错误就是类名首字母必须大写并且每行只允许有一条代码,这是规范

我觉得最简单的解决办法就是:

[Java] 纯文本查看 复制代码
package Qb;

public class Txx {

        public static void main(String[] args) {
                
                double b = 3.0;
                double sum = 30000;
                double q=0.1;
                double c = b + q;
                for (int i = 1;i <= 3;i++) {
                        sum = sum + c*360;
                        System.out.println(sum);
                        q+=0.1;
                        
                }
        }

}

运行结果如下:


但是我觉得楼主是不想创建新的变量,所以我又想办法:

[Java] 纯文本查看 复制代码
package Bb;

import java.text.DecimalFormat;

public class Qe {

        public static void main(String[] args) {
                double b = 3.0;
                double sum = 30000;
                float i = 0.1f;
                double c =b+i;
                while (i <= 0.3) {
                        sum=sum+c*360;
                        DecimalFormat df = new DecimalFormat("0.0");
                        System.out.println(df.format(sum));
                        i += 0.1;
                }
        }

}


运行结果如下:


我们发现,结果不对,因为Double精度丢失,0.3变成0.30000000000000004     循环条件就不对了,这个我也很无奈啊,期待大牛给一个解决方案
循环条件只能改成i<0.4才可以正常运行,继续测试吧,这个一目了然,还是给大家演示一下吧
[Java] 纯文本查看 复制代码
package Bb;

import java.text.DecimalFormat;

public class Qe {

        public static void main(String[] args) {
                double b = 3.0;
                double sum = 30000;
                float i = 0.1f;
                double c =b+i;
                while (i < 0.4) {
                        sum=sum+c*360;
                        DecimalFormat df = new DecimalFormat("0.0");
                        System.out.println(df.format(sum));
                        i += 0.1;
                }
        }

}



我会的也只有这些,觉得有帮助可以送我热心哦,小弟初学Java

发帖之后发现,图片都是在底部,有顺序的

这是该楼主代码运行原图

这是该楼主代码运行原图

简单的办法解决图

简单的办法解决图

不增加新的变量解决方案

不增加新的变量解决方案

最终的解决方案,还是不太彻底

最终的解决方案,还是不太彻底

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
我爱小彤 + 1 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

  • · Aarow|主题: 988, 订阅: 304

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

InvictusLee 发表于 2017-5-7 10:16
我觉得可能是这样:
原因:之所以会丢失精度,是因为在Java中二进制是无法精确的表示0.1的 ;就像十进制无法精确的用小数表示1/3一样;
如果非要修改:所有数字,以及他们之间的加减乘除,大于,小于,等于运算关系都用BigDecimal类对象类表示;
 楼主| 尘缘丶 发表于 2017-5-7 01:57
难道论坛不可以图文并茂的发表帖子吗?之前没技术不敢发帖,所以不懂,图片顺序都是有的,大家可以按运行结果看
piupiuoox 发表于 2017-5-7 03:24
xiaofeng55baby 发表于 2017-5-7 05:05 来自手机
太专业看不懂
巨无霸 发表于 2017-5-7 08:20
Java学完了,感觉自己也是个弱鸡,什么都不会!
rox 发表于 2017-5-7 09:35
曾经有个项目里面的经验,是把系统里面约定好最大小数位后,小数全部转换成整数后加减乘除,结果也只取整数,然后,再统一转小数。
最大的缺点就是,一旦数字过大,计算起来,可能会越界。
benbenxiong 发表于 2017-5-7 09:58
bigdecimal轻松解决而且double还有存储限制数字过大会直接报错的
sanshengmu 发表于 2018-3-14 00:29
弱鸡路过此贴。。。
相逢何必曾相识! 发表于 2018-3-18 23:19 来自手机
不太懂,有空研究下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 13:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表