`
paddy.w
  • 浏览: 497511 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

double类型运算精度丢失

    博客分类:
  • Java
阅读更多
        前段时间看了一点python入门,写了几个运算的例子,就发现浮点数进行运算的结果并不是期望的,而是接近与期望的一个数。比如期望结果是2.4,那么实际结果可能是2.333333339,当时参考的资料上说不用在意这个,由于是入门,我也就没太在意,就当是python自己的一个问题吧。昨天在网上闲逛,又无疑碰到了这个问题,不过这个是在java下发生的。于是写了点例子,发现这个问题并非与特定语言有关,而是与计算机底层实现有关,下面就说一下这个问题。
        需要注意,如果在java中使用浮点数,则默认为double。如果需要使用float,在浮点数后面加f。
public class Test {

	public static void main(String[] args) {
		System.out.print("直接输出2.4:");
		System.out.println(2.4);
		System.out.print("2.4/0.1:");
		System.out.println(2.4/0.1);
		System.out.print("(2.4-0.2)/0.1:");
		System.out.println((2.4-0.2)/0.1);
		System.out.print("直接输出2.2:");
		System.out.println(2.2);
		System.out.print("2.2/0.1:");
		System.out.println(2.2/0.1);
		System.out.print("(2.2+0.2)/0.1:");
		System.out.println((2.2+0.2)/0.1);
        System.out.print("2.2+0.2:");
        System.out.println(2.2+0.2);
	}
}

输出结果:
直接输出2.4:2.4
2.4/0.1:23.999999999999996
(2.4-0.2)/0.1:21.999999999999996
直接输出2.2:2.2
2.2/0.1:22.0
(2.2+0.2)/0.1:24.000000000000004
2.2+0.2:2.4000000000000004


        我们从源代码和输出的结果进行分析。首先从结果可以知道直接输出浮点数2.2和2.4没有问题,一切正常。但是2.4/0.1我们期望应该是输出24,却输出了23.999999999999996;同样的,(2.4-0.2)/0.1期望输出是22,实际输出是21.999999999999996,(2.2+0.2)/0.1也是同样的情况。这些现象说明我们得到了非期望值,一个“错误的结果”,也就是说,在计算过程中发生了精度丢失。
        前面说过,我在python中也有这样的问题,所以这种现象并不针对某种语言,而是计算机的实现造成的。众所周知,计算机只能识别二进制,所以我们的一切数据最后都转化为二进制来实现。我们发现,直接输出2.4和2.2并没有任何问题,但是一旦让其参与运算就会出错,因此精度丢失是发生在”运算“过程中的。
        浮点数由两部分组成,指数和尾数。如果在转换过程中进行了运算,那么所得结果将不可知,不能保证二进制能正好准确转换为十进制。其原理参见其他参考书。
        如何处理这种情况呢,可以用BigDecimal,具体使用参见JavaAPI。
分享到:
评论

相关推荐

    Java Double 精度问题总结

    使用Java,double 进行运算时,经常出现精度丢失的问题,总是在一个正确的结果左右偏0.0000**1。 特别在实际项目中,通过一个公式校验该值是否大于0,如果大于0我们会做一件事情,小于0我们又处理其他事情。 这样的...

    Java中double类型下出现精度计算错误情况下出力方法

    Java中的简单浮点数类型float和double不能够进行运算,因为大多数情况下是正常的,但是偶尔会出现如上所示的问题。这个问题其实不是JAVA的bug,因为计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制...

    jisuanqi.rar_double精度

    VC++下的四则运算,尤其是在考虑到double型时的精度丢失问题

    Java与MySQL中小数保存问题解析.pptx.pptx

    在进行浮点数运算时,可能会出现精度丢失的问题,例如0.1+0.2的结果并不等于0.3,而是近似于0.30000000000000004。 数据库字段类型选择 在设计数据库表结构时,需要对涉及小数的字段选择合适的数据类型,如DECIMAL...

    C语言不同数据类型的混合运算

    1、在运算过程中,如果参与运算的数据类型不同时,数据将由低类型转化为高类型,即’A’由char类型转换为double类型;(存储长度较短的转换为存储长度较长的,且不丢失精度) 2、在赋值运算时,如果赋值号两边的数据...

    JAVA8大数据类型.pdf

    JAVA8⼤数据类型 ⼤数据类型 8⼤基本数据类型 8⼤基本数据类型在内存中占⽤的⽐特... 具体规则为:double float long int short(char) byte 语法格式为:(转换到的类型)需要转换的值 注意:⼩转⼤会有丢失精度的问题!

    Java-关于基本数据类型中浮点数计算产生的精度问题

    在基本数据类型中,float和double都表示浮点型数据,而计算机计算采取的是对二进制的计算,所以会存在一定程度上的精度丢失问题。 BigDecimal类是一个大小数操作类,可以用来对超过16位有效位的数据进行精确的运算,...

    Java的8大基本数据类型.pdf

    Java的 的8⼤基本数据类型 ⼤基本数据类型 Java8⼤基本数据类型 ⼤基本数据类型 byte(字节型)、short(短整型)、int (整型) 、long(长整型) float(单精度浮点型)、double(双精度浮点型)、boolean(布尔型)、...

    C语言程序设计标准教程

    其类型说明符为float 单精度说明符,double 双精度说明符。在Turbo C中单精度型占4个字节(32位)内存空间,其数值范围为3.4E-38~3.4E+38,只能提供七位有效数字。双精度型占8 个字节(64位)内存空间,其数值范围...

    整理后java开发全套达内学习笔记(含练习)

    注意:默认类型转换(自动类型提升)会丢失精度,但只有三种情况: int>float; long>float; long>double. 看一下他们的有效位就明白。 二进制是无法精确的表示 0.1 的。 进行高精度运算可以用java.math包中...

    java计算器程序.doc

    //需要解决的问题,数学的运算都有正负号的出现,在点击等号的时候就会有冲突,应该怎样解决,经验:双精度浮点型数据类型是会像后减一位。0.7会显示成0.69999999 public class app74 { static int i=0; static ...

Global site tag (gtag.js) - Google Analytics