- 浏览: 378640 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
真的全站唯一:
描述的能不能准确一点,我也以为bigDecimal性能比dou ...
【性能】Java BigDecimal和double性能比较 -
zhanggang807:
学习到了。。以后会考虑往这方面设计
【java规范】Java spi机制浅谈 -
Xiong506:
xiyuan1025 写道你这是在linux下吗,我在linu ...
[监控]Btrace监控简单笔记 -
Xiong506:
xiyuan1025 写道你这是在linux下吗,我在linu ...
[监控]Btrace监控简单笔记 -
Bll:
找不到实现类
【java规范】Java spi机制浅谈
由于对float或double 的使用不当,可能会出现精度丢失的问题。问题大概情况可以通过如下代码理解:
public class FloatDoubleTest { public static void main(String[] args) { float f = 20014999; double d = f; double d2 = 20014999; System.out.println("f=" + f); System.out.println("d=" + d); System.out.println("d2=" + d2); } }
得到的结果如下:
f=2.0015E7
d=2.0015E7
d2=2.0014999E7
从输出结果可以看出double 可以正确的表示20014999 ,而float 没有办法表示20014999 ,得到的只是一个近似值。这样的结果很让人讶异。20014999 这么小的数字在float下没办法表示。带着这个问题,一起学习一下浮点数,做个简单分享,希望有助于大家对java 浮点数的理解。
1.关于 java 的 float 和 double 的表示法
Java 语言支持两种基本的浮点类型: float 和 double 。java 的浮点类型都依据 IEEE 754 标准。IEEE 754 定义了32 位和 64 位双精度两种浮点二进制小数标准。
IEEE 754 用科学记数法以底数为 2 的小数来表示浮点数。
对于32 位浮点数float用 第1 位表示数字的符号,用第2至9位来表示指数,用 最后23 位来表示尾数,即小数部分。
float(32位):
对于64 位双精度浮点数,用 第1 位表示数字的符号,用 11 位表示指数,52 位表示尾数。
double(64位):
都是分为三个部分:
(1) 一个单独的符号位s 直接编码符号s 。
(2)k 位的幂指数E ,移码表示 。
(3)n 位的小数,原码表示 。
2. 什么时候会出现无法表示?
任何一个数字,在java底层表示都必须转换成这种科学计数法来表示,那么我们来想想看什么时候这个数字会无法表示呢?那么只有两种情形:
1.幂数不够表示了:这种情况往往出现在数字太大了,超过幂数所能承受的范围,那么这个数字就无法表示了。如幂数最大只能是10,但是这个数字用科学计数法表示时,幂数一定会超过10,就没办法了。
2.尾数不够表示了:这种情况往往出现在数字精度太长了,如1.3434343233332这样的数字,虽然很小,还不超过2,这种情况下幂数完全满足要求,但是尾数已经不能表示出来了这么长的精度。
3. 20014999 为什么用 float 没有办法正确表示?
通过以上分析,应该已经知道,这个数字不大,转换成IEEE754科学计数法之后幂数一定是满足要求的,只是尾数不能表示这么精确的数字了。
结合 float和double的表示方法,通过分析 20014999 的二进制表示就可以知道答案了。
以下程序可以得出 20014999 在 double 和 float 下的二进制表示方式。
输出结果如下:
Double:100000101110011000101100111100101110000000000000000000000000000
Float:1001011100110001011001111001100
对于输出结果分析如下。对于都不
double
的二进制左边补上符号位
0
刚好可以得到
64
位的二进制数。根据double的表示法,分为符号数、幂指数和尾数三个部分如下:
0
10000010111
0011000101100111100101110000000000000000000000000000
对于
float
左边补上符号位
0
刚好可以得到
32
位的二进制数。
根据float的表示法,
也分为
符号数、幂指数和尾数三个部分如下
:
0
10010111
00110001011001111001100
绿色部分是符号位,红色部分是幂指数,蓝色部分是尾数。
对比可以得出:
符号位都是
0
。
幂指数为移码表示,两者刚好也相等。
唯一不同的是尾数。
在
double
的尾数为:
001100010110011110010111
0000000000000000000000000000
,省略后面的零,至少需要24位才能正确表示
。
而在
float
下面尾数为:
00110001011001111001100
,共
23
位。
为什么会这样?原因很明显,因为
float 尾数
最多只能表示
23
位,所以
24
位的
001100010110011110010111
在
float
下面经过四舍五入变成了
23
位的
00110001011001111001100
。所以
20014999
在
float
下面变成了
20015000
。public class FloatDoubleTest3 {
public static void main(String[] args) {
double d = 20014999;
long l = Double.doubleToLongBits(d);
System.out.println(Long.toBinaryString(l));
float f = 20014999;
int i = Float.floatToIntBits(f);
System.out.println(Integer.toBinaryString(i));
}
}
也就是说
20014999
虽然是在float的表示范围之内,但
在
IEEE 754
的
float
表示法精度长度没有办法表示出
20014999
,而只能通过四舍五入得到一个近似值。
小结
浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。尤其在使用
float
和
double
作精确运算的时候要特别小心。
可以考虑采用一些替代方案来实现。如通过
String
结合
BigDecimal
或者通过使用
long
类型来转换。
发表评论
-
Xml ResourceBundle简单实现
2012-04-17 21:45 4468ResourceBundle主要是用于和本地语言环境相关的一些 ... -
【maven】多子模块maven模板工程archetype创建过程
2012-04-02 20:55 17663最近项目里需要创建一 ... -
【java基础】如何设计java应用程序的平滑停止
2012-03-05 23:44 11019java应用程序退出的触发机制有: 1.自动结束:应用没有存 ... -
【java并发】juc Executor框架详解
2012-02-26 13:55 12509Executor 框架是 juc 里提供的线程池的实现。 ... -
【java并发】juc高级锁机制探讨
2012-02-23 00:52 8719最近在看一些j ... -
【java并发】基于JUC CAS原理,自己实现简单独占锁
2012-02-14 13:47 7867synchronized的基本原理回 ... -
[NoSQL]MongoDB初体验
2012-01-05 16:06 3969因为未来业务发展的一 ... -
【JVM】HotSpot JVM内存管理和GC策略总结
2011-12-13 22:05 15970JVM的相关知识是学习java ... -
32位机器下的一个java.lang.OutOfMemoryError错误分析
2011-10-17 11:19 2598昨天在本人windows机器( ... -
[监控]Btrace监控简单笔记
2011-09-09 10:57 5064前阵子看了公司网站的一个cache 命中率统计的btrace监 ... -
DBCP数据源配置项记录
2011-09-01 20:22 3001网站最近发生了数据库连接爆掉的问题。排查了下各个应用存在 ... -
【性能】Java BigDecimal和double性能比较
2011-08-28 20:06 14257我们知道 java 里面有个 BigDecimal ... -
【Spring】IOC容器并发条件下,可能发生死锁
2011-08-28 17:07 69431.背景 上周在生产环境应用启 ... -
JDK7 AIO 初体验
2011-08-17 19:20 2606JDK7 AIO初体验 JDK7已经releas ... -
如果要用java实现算法,一定慎用递归
2011-04-06 20:41 12964现象 : 递归是我们很经典的一种算法实现,可以很好的 ... -
java日志,需要知道的几件事(commons-logging,log4j,slf4j,logback)
2011-02-28 17:12 46410java日志,需要知道的几件事 如果对于comm ... -
JVM问题诊断常用命令:jinfo,jmap,jstack
2010-08-17 17:55 125021.jinfo 描述:输出给定 java ... -
一个枚举类的方法设计
2010-06-21 15:28 1691public enum ActionType { A ... -
java内部字符编码浅析
2010-06-07 21:43 6860java内部字符编码浅析 本周遇到一个 ... -
JDK反射之JDK动态proxy
2010-06-07 21:27 4125JDK动态代理 JDK 动态代理是 java 反射的一 ...
相关推荐
浮点数在计算机内部是以二进制表示的,这与我们通常使用的十进制系统不同,因此在进行浮点数运算时可能会出现精度丢失的问题。这篇博客主要探讨了Java中浮点数(包括`float`和`double`类型)运算的特性、存在的问题...
浮点数计算在Java中常常会遇到精度损失的问题,这是由于计算机硬件的限制以及浮点数在二进制表示上的特性所导致的。在Java中,浮点数类型包括单精度浮点数`float`(4字节,32位)和双精度浮点数`double`(8字节,64...
虽然 `double` 提供了相对较高的精度,但在涉及精确数学运算(特别是涉及到小数值)时,由于其内部采用二进制浮点数格式存储,仍会出现精度丢失的情况。这种精度丢失的现象对于需要高精度计算的应用来说是一个常见的...
对于Java开发者来说,这个转换器可能会使用Java的`java.nio.ByteBuffer`类来处理字节顺序,以及`Float.intBitsToFloat()`方法来完成从整数到浮点数的转换。此外,源码可能还包含错误检查和用户界面部分,以确保输入...
在给定的`DoubleUtil.java`文件中,可能包含了一些处理浮点数精度问题的实用工具方法,比如四舍五入、比较或转换为特定精度的字符串。通过阅读和理解这些方法,我们可以学习到更多关于如何在实际编程中应对浮点数...
在基本数据类型中,float和double都表示浮点型数据,而计算机计算采取的是对二进制的计算,所以会存在一定程度上的精度丢失问题。 BigDecimal类是一个大小数操作类,可以用来对超过16位有效位的数据进行精确的运算,...
在Java编程中,使用`float`和`double`类型进行浮点数计算时经常会遇到精度丢失的问题。这是因为浮点数在计算机内部是以二进制形式存储的,而某些十进制小数无法用二进制精确表示,从而导致计算结果出现误差。例如,`...
Java 双精度浮点数精度问题解决方案 Java 中的双精度浮点数(double)类型在进行运算时经常出现精度丢失的问题,这是由于双精度浮点数在计算机内部的存储方式所致。双精度浮点数使用 64 位二进制数来存储小数,然而...
同时,在处理非常小的数值时,确保不小于`float`或`double`的最小值,可以防止因为数值过小而导致的精度丢失。 此外,浮点数的比较也需要注意,由于浮点数的不精确性,直接使用`==`进行比较可能会导致错误的结果。...
在编程领域,浮点数计算由于涉及到二进制表示法,常常会出现精度丢失的问题,这在需要精确计算的场景下尤为棘手。Java作为一种广泛使用的编程语言,也面临同样的挑战。为了解决这个问题,我们可以利用特定的设计和...
这种问题的出现是因为 Excel 中的数值单元格在读取时,可能会被格式化为浮点数,从而导致精度损失。 例如,在 Excel 单元格中输入 1,读取后可能会变成 1.0,而输入 2.2 可能会变成 2.1999999997。这种情况下,我们...
这个问题其实不是JAVA的bug,因为计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制转化为十进制浮点数时,精度容易丢失,导致精度下降。 要保证精度就要使用BigDecimal类,而且不能直接从double...
然而,由于浮点数的二进制表示方式,当进行某些计算或转换时,可能会出现精度丢失的问题。标题提到的“double类型精度丢失;double转换到64位整数”就涉及到这一关键概念。 精度丢失通常发生在以下几种情况: 1. *...
解决java数值范围以及float与double精度丢失的问题 Java中的数值范围和浮点数精度问题是许多开发者经常遇到的问题。下面我们将详细探讨Java中的数值范围、float和double类型的精度问题,并且提供解决方案。 一、...
JS 数字精度丢失的一些典型问题 JS 数字精度丢失的原因 解决方案(一个对象+一个函数) 一、JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加 0.1 + 0.2 != 0.3 // true 这真不是 Firebug 的问题,可以用...
这样的工具可以帮助开发者更好地理解和处理浮点数精度问题,避免因为浮点数比较错误导致的程序逻辑问题。 解决精度问题的方法有很多,如使用更高精度的数据类型(如Java中的`BigDecimal`),或者使用特定的算法进行...
浮点数和十六进制(hex)之间的转换是计算机科学中的基本操作,特别是在编程和数据解析领域。在处理浮点数时,计算机...在编程时,正确地进行这种转换能够确保数据的准确无误,避免因精度丢失或格式错误导致的问题。
常见问题还包括在进行浮点数运算时可能出现的精度丢失,以及在设计数据库表结构时选择合适的数据类型。例如,如果业务逻辑要求精确存储和计算小数,那么选择DECIMAL而非FLOAT或DOUBLE会更为合适。 总的来说,理解和...
在Java中,我们经常需要将Java对象序列化为JSON字符串,或者将JSON字符串反序列化为Java对象。这个过程涉及到两个关键库:Fastjson和Jackson,这两个库都是Java中非常流行的JSON处理库。 **Fastjson** Fastjson是...
通常,Java中的`double`和`float`类型在进行数学运算时由于二进制浮点数的表示方式,会存在精度损失。例如,0.1 + 0.2并不等于0.3,而是非常接近但不完全相等的一个值。这种现象是由IEEE 754浮点数标准导致的,而非...