zoukankan      html  css  js  c++  java
  • float与double基本数据类型分析

    float 大小为 32-bit  

    存储的结构:1位符号位,8位指数(幂),23位尾数

    double 大小为 64-bit    

    存储的结构:1位符号位,11位指数(幂),52位尾数

    float与double结构类似,下面以float为例子做分析:

    1、通过程序的方式获取float的二进制表示:

    public class FloatTest {  
        public static void main(String[] args) {  
            float f = 8;  
            //因为int型与float型在内存中的长度相同,用floatToIntBits()可以把float中的二进制标示转为int型表示。类似double可转为long
            int i = Float.floatToIntBits(f); 
            System.out.println(Integer.toBinaryString(i)); 
        } 
    } 

    2、通过计算的方式获取float的二进制表示:

    以float f = 20014999 为例

      1)20014999 的二进制为1001100010110011110010111

      2)规格化后 1.001100010110011110010111*2^24

         尾数为001100010110011110010111

           此时24位,但float的尾数只有23位。四舍五入后为00110001011001111001100

      3)幂为24+127 二进制为:10010111。

        其中127为 float的偏移附加,double的偏移附加为1023。具体解释参照:IEEE 754 (二进制浮点数算术标准)

      4)加上符号位0。  0表示正数,1表示负数

      最后,内存中的表示为:0 10010111 00110001011001111001100

    上面的过程中可以看出float精度丢失的原因。需要高精度,如金额的计算不能用浮点型,一般可用BigDecimal。

    使用BigDecimal需要注意的一点是:BigDecimal 也有一些令人奇怪的行为。尤其在使用 equals() 方法来检测数值之间是否相等时要小心。 equals() 方法认为,两个表示同一个数但换算值不同(例如, 100.00 和 100.000 )的 BigDecimal 值是不相等的。然而, compareTo() 方法会认为这两个数是相等的,所以在从数值上比较两个 BigDecimal 值时,应该使用 compareTo() 而不是 equals() 。

     3、float、double、long型 常量的表示问题。

      float 型常量后面加F  or   f   如   3.14f

      double 型常量后面加D  or   d   或者不加    3.14d  or  3.14(默认为双精度)

      long 型常量   加L or  l 

      int 型常量     不加后缀

      一般我们都不加这个后缀,其实是因为程序做了类型转换。

      但当超出范围时需要注意。

      如:

    long L1 = 8888888888;//会报错,因为8888888888为int型常量,但超出了int的范围。

    *花边知识:

    1、计算机上表达实数有两中方法:定点表示(fixed-point)和浮点表示(floating-point)。

    2、上面的提到的方法Float.floatToIntBits()的jdk 1.7的源码如下:

        public static int floatToIntBits(float value) {
            int result = floatToRawIntBits(value);
            // Check for NaN based on values of bit fields, maximum
            // exponent and nonzero significand.
            if ( ((result & FloatConsts.EXP_BIT_MASK) ==
                  FloatConsts.EXP_BIT_MASK) &&
                 (result & FloatConsts.SIGNIF_BIT_MASK) != 0)
                result = 0x7fc00000;
            return result;
        }

    其中的 floatToRawIntBits();方法的实现为:

     public static native int floatToRawIntBits(float value);

    这里用到native因为这个方法的实现需要操作内存,所以但在java无法实现,只能通过调用C语言来实现底层的操作。

     3、前人研究:

     java float double精度为什么会丢失?浅谈java的浮点数精度问题

    http://blog.csdn.net/abing37/archive/2010/02/27/5332798.aspx

    Java中的double类型数据存储探析

    http://blog.csdn.net/softwater007/archive/2008/11/18/3330619.aspx

    IEEE754 学习总结

    http://www.pediy.com/bbshtml/BBS6/pediy6610.htm

    使用浮点数和小数中的陷阱

    http://www.360doc.com/content/07/0308/10/14474_388882.shtml

    4.相关规范

    IEEE754:http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html

    SUN 公司的 http://docs.sun.com/source/806-3568/ncg_math.html

  • 相关阅读:
    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
    Visual Studio断点调试, 无法监视变量, 提示无法计算表达式
    ASP.NET MVC中MaxLength特性设置无效
    项目从.NET 4.5迁移到.NET 4.0遇到的问题
    发布网站时应该把debug设置false
    什么时候用var关键字
    扩展方法略好于帮助方法
    在基类构造器中调用虚方法需谨慎
    ASP.NET MVC中商品模块小样
    ASP.NET MVC中实现属性和属性值的组合,即笛卡尔乘积02, 在界面实现
  • 原文地址:https://www.cnblogs.com/wuchangming/p/2983559.html
Copyright © 2011-2022 走看看