前段时间看了一点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 进行运算时,经常出现精度丢失的问题,总是在一个正确的结果左右偏0.0000**1。 特别在实际项目中,通过一个公式校验该值是否大于0,如果大于0我们会做一件事情,小于0我们又处理其他事情。 这样的...
Java中的简单浮点数类型float和double不能够进行运算,因为大多数情况下是正常的,但是偶尔会出现如上所示的问题。这个问题其实不是JAVA的bug,因为计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制...
VC++下的四则运算,尤其是在考虑到double型时的精度丢失问题
在进行浮点数运算时,可能会出现精度丢失的问题,例如0.1+0.2的结果并不等于0.3,而是近似于0.30000000000000004。 数据库字段类型选择 在设计数据库表结构时,需要对涉及小数的字段选择合适的数据类型,如DECIMAL...
1、在运算过程中,如果参与运算的数据类型不同时,数据将由低类型转化为高类型,即’A’由char类型转换为double类型;(存储长度较短的转换为存储长度较长的,且不丢失精度) 2、在赋值运算时,如果赋值号两边的数据...
JAVA8⼤数据类型 ⼤数据类型 8⼤基本数据类型 8⼤基本数据类型在内存中占⽤的⽐特... 具体规则为:double float long int short(char) byte 语法格式为:(转换到的类型)需要转换的值 注意:⼩转⼤会有丢失精度的问题!
在基本数据类型中,float和double都表示浮点型数据,而计算机计算采取的是对二进制的计算,所以会存在一定程度上的精度丢失问题。 BigDecimal类是一个大小数操作类,可以用来对超过16位有效位的数据进行精确的运算,...
Java的 的8⼤基本数据类型 ⼤基本数据类型 Java8⼤基本数据类型 ⼤基本数据类型 byte(字节型)、short(短整型)、int (整型) 、long(长整型) float(单精度浮点型)、double(双精度浮点型)、boolean(布尔型)、...
其类型说明符为float 单精度说明符,double 双精度说明符。在Turbo C中单精度型占4个字节(32位)内存空间,其数值范围为3.4E-38~3.4E+38,只能提供七位有效数字。双精度型占8 个字节(64位)内存空间,其数值范围...
注意:默认类型转换(自动类型提升)会丢失精度,但只有三种情况: int>float; long>float; long>double. 看一下他们的有效位就明白。 二进制是无法精确的表示 0.1 的。 进行高精度运算可以用java.math包中...
//需要解决的问题,数学的运算都有正负号的出现,在点击等号的时候就会有冲突,应该怎样解决,经验:双精度浮点型数据类型是会像后减一位。0.7会显示成0.69999999 public class app74 { static int i=0; static ...