float类型与double类型数谁更大?

float类型与double类型数谁更大?

double i=2.7与float j=2.7谁大?double i=0.7与float j=0.7谁大?

   首先来了解一下float类型和double类型在内存是如何存储的?

无论是单精度还是双精度在存储中都分为三个部分:

符号位(Sign) : 0代表正,1代表为负

指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储

尾数部分(Mantissa):尾数部分

其中float的存储方式如下图所示:

 

                                 1                   8                                       23

                               符号位       指数位                              尾数部分

 

而双精度的存储方式为:

 

                                 1                   11                                       52

                               符号位       指数位                              尾数部分

 

   那么十进制2.7,转换成二进制为:10.101100 1100 1100 1100 1100.......(为了更加直观,循环部分加了下划线和空格),由上面的基础知识我们知道,float类型只会保存23位尾数,double类型只会保存52位尾数。那么后面的数是如何截断的呢?是直接扔掉还是其他方法?

   假设保存的数据到达限定的位数后直接扔掉,那么根据推理,double保存的位数多,double应该比较大。接下来让我们做实验来判断二者谁更大?

   代码如下:(用float跟double比较,判断boolean值。)

float a=2.7f;

double a1=2.7;

System.out.println((a>a1));

 

float b=0.7f;

double b1=0.7;

System.out.println((b>b1));

   实际运行结果如下:

       true

       false

   实验结果很出乎意料,并不是说double一定比float大。那么我们做如下猜测:在发生截取的时候并不是简单的丢弃,而是存在某种规则,类似于“四舍五入”,运用于二进制,可能就是“零舍一入”。

   根据假设,如果是“零舍一入”,那么十进制的2.7和0.7在表示成float类型和double类型分别如下:

   Float:十进制数2.7在二进制的科学计数法表示中,其小数点后第23位(红色)是:0,第24位(绿色)是:1,如下:

2.7的二进制科学计数法:*1.0101100 1100 1100 1100 1100 1100.......

   根据“零舍一入”最终记录到内存中的float数是:*1.0101100 1100 1100 1100 1101(第23位发生变化,进位为1)

 

   Double:十进制数2.7在二进制的科学计数法表示中,其小数点后第52位(红色)是:1,第53位(绿色)是:1,如下:

   2.7:*1.010 1100 1100 ...(中间省略8个1100).... 1100 1100 1100.......

   根据“零舍一入”最终记录到内存中的double数是:*1.0101100 1100 ...(中间省略8个1100).... 1100 11010(第22和23位发生变化,进位为1)

 

   同样的道理:十进制数0.7的float类型和double类型在内存中的表示如下:

二进制科学计数法:*1.0 1100 1100 1100 1100 1100 1100 (23为红,24为绿)

   Float:*1.01100 1100 1100 1100 1100 1(未进位)

 

二进制科学计数法:*1.0 1100 1100 ...(中间省略8个1100)... 1100 11001100 ....

   Double:*1.01100 1100 ...(中间省略8个1100)... 1100 1100110(未进位)

 

如果上述猜测正确,我们可以得到:

   1.float 2.7大于double 2.7,因为float的进位比double的进位高。

   2.double 2.7大于真实的2.7,float 2.7也大于真实的2.7,因为两者都进位了。

   3.float 0.7小于double 0.7,虽然两者都没有发生进位,但是double精度大,表示的数范围大,比float多出来小数后24~52位。  

   4.double 0.7和float0.7都小于真实的0.7,因为没有进位且丢弃了后面小数部分。

  (上述猜测的1、3已证明,2、4无法证明,因为无法在计算机内表示真实的数,但是我们可以通过其他途径证明)

   选择不会发生小数位丢弃的十进制数2.25,二进制表示:10.01

   二进制科学计数法:*1.001
   因此无论是double还是float还是真实值都是一样大的。

   代码如下:

float a=2.25f;

double a1=2.25;

System.out.println((a1==a));

   实际运行结果如下:

    true

 

例题:What will be the output of the program? (2016年中科大软院机试真题)

     #include

     int main( ){

         float a = 0.7;

           if (0.7 > a)

                printf ( "Hi\n " ) ;

           else

                printf ( "Hello\n " ) ;

           return 0 ;

        }

A.  Hi                       B.  Hello

C.  Hi Hello                  D.  None of above

 

Answer: Option A

Explanation:  if (0.7 > a) here is a float variable and 0.7 is a double constant. The double constant 0.7  is greater than the float variable a.  Hence the if  condition is satisfied and  it prints‘Hi’。

你可能感兴趣的:(软工基础)