Java普通类型计算出错的问题

原创 2018年04月15日 14:58:25

问题的产生

今天同学问了我一个问题,给了一段代码,问运行结果:
这里写图片描述
第一眼看上去感觉就是0.8啊,没毛病,可是要是这么简单的题怎么会问我呢,感觉是个陷阱啊,这时候想起来,浮点数的存储不是精确的,但是依然得不出答案,于是上IDE编译运行了一遍。
这里写图片描述
结果:0.79999995
其实不只是减法,加法也可能发生这种情况,可以参考 这里。是不是很奇怪呢,让我们一起去探索究竟。

原因

浮点数在内存中是按照IEEE754标准进行存储的,详细的介绍请Google或者百度,或者参考这篇文章 得到浮点数的二进制
原因就是计算机内部是通过二进制也就是0和1来存储数据的,浮点数也不例外,但是有些浮点数是无法精确存储的,看了上面那篇文章应该可以理解,只有由2的幂组成的数才可以精确存储。

2.0f在内存中可以准确的存储,这是2.0f的二进制存储图:
这里写图片描述

1.2f就无法精确的存储:
这里写图片描述

经过换算可以得到1.2f在内存中存储的其实是 1.2000000476837158203125E0
这里就可以体现出浮点数是在一定精度内还是准确的。

因为1.2f后面还有很多多余的数字,进行减法就相当于计算:
2.0 - 1.2000000476837158203125E0
它的结果就是0.7999999523162842
进行保留后就得到了我们输出的结果0.79999995

如何解决

通过java.math包中提供的BigDecimal类可以解决此类问题。
这里写图片描述

也一定要使用BigDecimal类中参数类型为String的构造函数
这里写图片描述

不然还是的不到正确的结果:
这里写图片描述

这是因为以String为参数的构造函数内部是采用字符串处理的,而以浮点数为参数,内部还是通过double类型实现,所以还是会出现精度损失的问题。

使用Java的到浮点数的二进制

得到浮点数的二进制这篇文章是使用C语言得到浮点数的二进制,使用java比C语言要简单,因为有方法可以调用。

可以使用Float类的静态方法floatToIntBits()或者floatToRawIntBits():
这里写图片描述

floatToIntBits()和floatToRawIntBits()的区别就在于当参数是NaN,floatToRawIntBits 不压缩所有将 NaN 编码为一个“规范”NaN 值的位模式。
这里写图片描述

java语言基础(10)——类型强制转换时的数据溢出计算

我们定义 byte=130;这在编译中会报错。
  • wang740209668
  • wang740209668
  • 2017-02-28 22:11:31
  • 329

Java对日期Date类型进行运算

先来几行代码: Date d=new Date(); SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd"); System.o...
  • diweikang
  • diweikang
  • 2017-06-05 21:31:51
  • 2009

java double类型运算问题

问题重现: double i = 0.1; System.out.println(i+i+i); 运行上面的语句,最终的结果是: 很奇怪,并不是想象中的0.3,错误在哪里? 原因:这其实是计算...
  • u010900754
  • u010900754
  • 2016-04-13 14:12:33
  • 863

【Java】Java中两个float计算得出错误结果

Java中两个float计算Java中两个float计算 问题的产生 原因 如何解决 使用Java的到浮点数的二进制 问题的产生今天同学问了我一个问题,给了一段代码,问运行结果: 第一眼看上去感...
  • cflys
  • cflys
  • 2017-04-27 22:33:19
  • 2010

java 浮点数 运算出错

java 浮点 运算出错
  • wangjun5159
  • wangjun5159
  • 2016-05-10 13:50:45
  • 1104

关于vitualBox创建共享磁盘的问题

报错: 将介质类型从 普通 更改为 可共享出错。 Cannot change type for medium 'E:\NewVirtualDisk1.vdi' to 'Shareable' since...
  • lihengfang
  • lihengfang
  • 2013-12-04 00:45:31
  • 3994

JAVA强制类型转换常见错误

这篇文章主要讲解:JAVA强制类型转换经常遇到的问题,主要分为2种情况。 1、当两个类没有继承关系时: package Test; public class Test { public stati...
  • guo_jia_liang
  • guo_jia_liang
  • 2016-11-18 10:02:14
  • 234

Java 基础知识(四)之基本类型与运算

1.   Java基本数据类型        Java一共提供了8种原始的数据类型(byte、short、int、long、float、double、char、boolean),这些数据类型不是对象...
  • why_still_confused
  • why_still_confused
  • 2016-05-15 11:52:18
  • 1250

java蓝桥杯时间转换

问题描述   给定一个以秒为单位的时间t,要求用“::”的格式来表示这个时间。表示时间,表示分钟,而表示秒,它们都是整数且没有前导的“0”。例如,若t=0,则应输出是“0:0:0”;若t=3661,...
  • wzt529
  • wzt529
  • 2017-03-09 21:17:42
  • 276

水塘抽样(Reservoir Sampling)问题

在高德纳的计算机程序设计艺术中,有如下问题:可否在一未知大小的集合中,随机取出一元素?。或者是Google面试题: I have a linked list of numbers of length ...
  • u012102306
  • u012102306
  • 2016-07-24 15:38:51
  • 1352
收藏助手
不良信息举报
您举报文章:Java普通类型计算出错的问题
举报原因:
原因补充:

(最多只允许输入30个字)