`
xubindehao
  • 浏览: 239265 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java中比较float和double的大小

阅读更多

 


分类: Java 553人阅读 评论(1) 收藏 举报

转自:http://blog.csdn.net/running8063/article/details/4093261

最近在项目中碰到了一个业务逻辑计算,代码如下(示例代码)

double val1 = ...;

double val2 = ...,

double dif = ...,

if (Math.abs(val1 - val2-dif) == 0){

  //do things

}

 

结果发现有一组数据:61.5,60.4,1.1无法达到正确的结果.有经验的开发人员一眼就可以发现问题所在,也知道应该采用如下的方式修改代码(产品模式下要进行代码的抽取和封装):

double exp = 10E-10;

if (Math.abs(val1 - val2-dif)>-1*exp && Math.abs(val1 - val2-dif)<exp){

 //do things

}

 

那为什么上面代码中"Math.abs(val1 - val2-dif) == 0"的值为什么会是false呢?这就引申到java的一个基础问题,即java中浮点数的存储机制.

 

Java 中的浮点数分为单精度和双精度数,也就是float和double.

 

float在内存中跟int一样,占4个字节,32 bit.

 

第1个bit表示符号,0表示正数,1表示负数,这个很好理解,不用多管.

 

第2-9个bit表示指数,一共8位(可以表示0-255),这里的底数是2,为了同时表示正数和负数,这里要减去127的偏移量.这样的话范围就是(-127到128),

另外全0和全1作为特殊处理,所以直接表示-126到127.

 

剩下的23位表示小数部分,这里23位表示了24位的数字,因为有一个默认的前导1(只有二进制才有这个特性).

 

     最后结果是:(-1)^(sign) * 1.f * 2^(exponent)

     这里:sign是符号位,f是23bit的小数部分,exponent是指数部分,最后表示范围是(因为正负数是对称的,这里只关心正数)

    2^(-126) ~~ 2(1-2^(-24)) * 2^127

    这个还不是float的取值范围,因为标准中还规定了非规格化表示法,另外还有一些特殊规定.

 

非规格化表示:

    当指数部分全0而且小数部分不全0时表示的是非规格化的浮点数,因为这里默认没有前导1,而是0.

    取值位0.f * 2^(-126),表示范围位 2^(-149)~~ (1-2^(-23)) * 2^(-126) 这里没有考虑符号.这里为什么是-126而不是-127? 如果是-127的话,那么最大表示为

2^(-127)-2^(-149),很显然2^(-127) ~~2^(-126) 就没法表示了.

 

 

其他特殊表示

    1.当指数部分和小数部分全为0时,表示0值,有+0和-0之分(符号位决定),0x00000000表示正0,0x80000000表示负0.

    2.指数部分全1,小数部分全0时,表示无穷大,有正无穷和负无穷,0x7f800000表示正无穷,0xff800000表示负无穷.

    3.指数部分全1,小数部分不全0时,表示NaN,分为QNaN和SNaN,Java中都是NaN.

 

结论:

    可以看出浮点数的取值范围是:2^(-149)~~(2-2^(-23))*2^127,也就是Float.MIN_VALUE和Float.MAX_VALUE.

 

References:

http://blog.csdn.net/treeroot/archive/2004/09/05/95071.aspx

http://hi.baidu.com/520miner/blog/item/698266ed9ee000d7b31cb1aa.html

 

分享到:
评论

相关推荐

    Java中BigDecimal的加减乘除、比较大小与使用注意事项

    对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精确计算的结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作,下面这篇文章给大家介绍了Java中BigDecimal的加减...

    JAVA程序员面试宝典

    原始类型封装类booleanBoolean charCharacter byteByte shortShort intInteger longLong floatFloat doubleDouble 引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和...

    java笔试题 大学生应聘

    原始类型封装类,booleanBoolean,charCharacter,byteByte,shortShort,intInteger,longLong,floatFloat,doubleDouble引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和...

    java笔试题大汇总

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    史上最全Java面试题目大集合

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    125条常见的java面试笔试题大汇总

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    Java测试题2答案

    定义一个类名为"MyClass.java"的类,并且该类可被一个工程中的所有类访问,那么该类的正确声明应为:CD A double a=1.0; A private class MyClass extends Object B class MyClass extends Object C ...

    java程序员面试技巧

    基本数据类型包括byte、int、char、long、float、double、boolean和short。 java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应 该用StringBuffer类 3、int 和...

    Java程序员面试宝典

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    java考试题大总结

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    125集专攻JAVA基础 JAVA零基础入门学习视频教程 动力节点JAVA视频教程.txt

    北京动力节点-Java编程零基础教程-059-Java基本语法-数据类型-float与double的区别.avi 北京动力节点-Java编程零基础教程-060-Java基本语法-数据类型-布尔型.avi 北京动力节点-Java编程零基础教程-061-Java基本...

    java面试笔试题大汇总

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    Java笔试题目汇总

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数 据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

    第5-20章深入描述了java技术的内部细节,包括垃圾收集、java安全模型、java的连接模型和动态扩展机制、class文件、运算及流程控制等等,其中等6章和附录a-c完全可以作为class文件和指令含集的参考手册。本书还附带...

    Java中的浮点数分析

     浮点数分为单精度和双精度,Java中的单精度和双精度分别为float和double.你们知道float和double是怎么存储的吗? float占4个字节,double占8个字节,为了方便起见,这里就只讨论float类型. float其实和一个int型的...

    java面试题

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    JAVA面试题最全集

    9.Java中访问数据库的步骤,Statement和PreparedStatement之间的区别。 10.找出下列代码可能存在的错误,并说明原因: 二、JSP&Servlet技术 1.描述JSP和Servlet的区别、共同点、各自应用的范围 2.在Web开发中...

    Java 关键字、标识符、注释、常量与变量、数据类型,算术、赋值、比较、逻辑、位、三元运算符和流程控制、break、continue

    Java中常量的分类: 1,整数常量。所有整数 2,小数常量。所有小数 3,布尔(boolean)型常量。较为特有,只有两个数值。true false。 4,字符常量。将一个数字字母或者符号用单引号( ' ' )标识。 5,字符串常量。...

    java 面试题 总结

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    积分java源码-money-profiling:使用JavaMoney和CurrencyAPI对ChronicleMap进行基准测试

    积分java源码Java 资金分析 Java Money Profiling探索了几种在 Java 中模拟货币金额的不同方法。...的float和double优先于整数,例如int 。 Float 和 double 可能会给粗心的开发人员带来很多麻烦。 我们

Global site tag (gtag.js) - Google Analytics