精华内容
下载资源
问答
  • 目录IEEE754浮点数标准指数位确定范围小数位确定精度总结 转换原则(低精度向高精度转换):byte->(short,char)->int->long->float->double IEEE754浮点数标准 IEEE754标准包含一组实数的二进制...

    • 转换原则(低精度向高精度转换):byte->(short,char)->int->long->float->double

    IEEE754浮点数标准

    • IEEE754标准包含一组实数的二进制表示法。它有三部分组成:符号位, 指数位, 尾数位
    • 三种精度的浮点数各个部分位数如下
    精度 符号 阶/指数 尾数
    单精度 1 8 23
    1. 第一部分用来存储符号位(sign),用来区分正负数,0正1负。
    2. 第二部分用来存储指数(exponent),指数也有正负之分,指数位确定大小范围。
    3. 第三部分用来存储小数(fraction),小数位决定了计算精度,因为小数位能表示的数越大,精度越大,数值越准确。

    指数位确定范围

    • 指数可能是负数,也有可能是正数。而有符号整数的计算是比无符号整数麻烦的。所以为了减少不必要的麻烦,在实际存储指数的时候,需要把指数转换成无符号整数。
    • 我们看到float的指数部分是8位,则指数的取值范围是 -126到+127,为了消除负数带来的实际计算上的影响(比如比较大小,加减法等),可以在实际存储的时候,给指数做一个简单的映射,加上一个偏移量,比如float的指数偏移量为127。

    小数位确定精度

    • float和double的精度是由尾数的位数来决定的
    • float:2^23 = 8388608,一共七位,由于最左为1的一位省略了,这意味着最多能表示8位数,但绝对能保证的为7位,也即float的精度为7~8位有效数字(算上整数的一位)
    • double:2^52 = 4503599627370496,一共16位,同理,double的精度为16~17位

    总结

    • long:2^63-1;
    • float : float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38
    • 所以:float的数据范围大于long的数据范围
    展开全文
  • 原因很简单,就是int类型是直接以二进制形式保存,而float类型是以指数形式保存。 下面内容对于初学者来说如果继续看下去收获肯定会不小,但是也会有一定的挑战,但还是希望你静下心,认真看下去。 目录一、背景二...
    • 原因很简单,就是int类型是直接以二进制形式保存,而float类型是以指数形式保存。
    • 下面内容对于初学者来说如果继续看下去收获肯定会不小,但是也会有一定的挑战,还是希望你静下心,认真看下去。

    一、背景

    • 这几天在写《算法设计与分析的作业》期间遇到了用int和float类型最大值,初始化变量的问题。查了一下,int可以用<limits.h>中的INT_MAX初始化,float可以用<float.h>中的FLT_MAX初始化,但是我就很难受,为什么都是基本类型的最大值,却要包含两个头文件,能不能偷懒,用int最大值直接去初始化float或者float最大值初始化int呢?按照以前的错误理解,int和float字节数相同,但是float有小数部分,所以它表示的范围更窄,我呢就写了一个程序看了下,这两个到底相差多大,偷懒的做法风险有多高,所以就写了下面的程序:
    #include <iostream>
    #include <limits.h>
    #include <float.h>
    using namespace std;
    int main()
    {
      cout<<INT_MAX<<endl;
      cout<<FLT_MAX<<endl;
      return 0;
    }
    
    

    结果如下:
    在这里插入图片描述

    • 不试不知道,一试吓一跳啊,float的表示范围怎么会那么大,该不会他们使用的内存空间不一样吧:
    #include <iostream>
    #include <limits.h>
    #include <float.h>
    using namespace std;
    int main()
    {
      cout<<INT_MAX<<endl;
      cout<<FLT_MAX<<endl;
      cout<<sizeof(int)<<endl;
      cout<<sizeof(float)<<endl;
      return 0;
    }
    
    • 结果:
      在这里插入图片描述
    • 果然是我太菜了,那就好好看下到底是怎么回事吧:

    二、int类型分析

    1、分析

    • int 用4字节保存,最多表示248=2322^{4*8} = 2^{32}, 有正数和负数,所以可表示23112^{31}-1个正数,即其最大值为2147483647,和上面结果一致,最小值-2147483648, 最大值比最小值的绝对值小1, 这是因为0占据了正数的一个表示名额。
    • 具体如下:
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    • 总共32位,也就是说它的能存储的数字就是32位全0,到32位全1。如果这 样的话它就只能存储正数了,但是我们计算也要用到负数,这可不太妙啊。所以为了能够即能存储正数又能够存储负数,科学家在设计计算机的时候把这32位数据进行了重新解释,从全0开始,一直到, 除最前一位之外,其余位都为1,这些表示他们对应的正数。就是下面这种形式
      从全0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

    到除第一位是0之外全都是1

    0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

    上面范围都表示正数。可以计算一下,上面这个数刚好就是对应的最大的int类型。

    • 剩下的都表示负数了,那么问题又来了,这些负数有分别是怎么表示的呢?
      我们接着上面的分析,最大的正数表示形式(就是上面写出来的除第一位是0之外全都是1的那个形式)在加一,就成了下面的样子:
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

    这个数被计算机解释为最小的负数,就是-2147483648,然后依次类推,32的表示形式每加1, 它所表示的形式也就加1,一直到最大的负数-1,32位表示形式就成了全1

    1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

    好了关于int存储大致解释清楚了,但是我掌握的这些到底对不对呢?下面我们使用汇编来看一下,到底是不是这样:

    2、验证(汇编)

    • 这里用mips汇编来查看其存储方式, 把下面这段代码在汇编器Qtspim中运行(运行前请先删除汉字注释):
    .data
    int_1: .word 0                                   ;定义了一个4字节的变量int_1,并把它赋值为0
    int_2: .word 2147483647		;定义了一个4字节的变量int_2,并把它赋值为2147483647
    int_3: .word -1					;定义了一个4字节的变量int_3,并把它赋值为-1
    int_4: .word -2147483648		;定义了一个4字节的变量int_4,并把它赋值为-2147483648
    .text
    main:
    	 lw $t1,int_1			;把上面定义的变量int_1取值到寄存器t1中
    	 lw $t2,int_2			;把上面定义的变量int_2取值到寄存器t2中
    	 lw $t3,int_3
    	 lw $t4,int_4
    		  
    

    查看寄存器情况如下:
    在这里插入图片描述
    和上面解释的情况相同。

    三、float类型分析

    1、分析

    • float同样也是4字节保存只不过他的保存形式式如下:
      在这里插入图片描述
    • 也就是说第一个位置是符号位,如果它为0表示正数,为1表示负数
    • 第2-9位共8个位是指数位,这里的指数位使用的是带偏阶的计数法1,就是说,这里存储的指数 = 真正指数+127,这里的127是它的偏阶。那么它最大能够存储多大的指数呢,8位最多能表示2812^{8}-1个数字也就是255个数字,从全0(0)到全1(255)。但是IEEE754的指数全1是不能表示数字的;真正指数 = 这里存的指数-127,所以最大能够存储的指数是254-127 = 127,最小能够存储的指数是1-127 = -126,这里最小用了1减,而没有用0,是因为当指数为0,而尾数非0,这不是规格化数。所以最终指数部分能够表示的范围是-126 ~ 127
    • 在看尾数部分,IEEE754隐藏了一个前导1,也就是说,这里存储的尾数 = 真正尾数 - 1,所以我们在将存储的数据还原为原先的数据时一定要加上1.

    2、验证(汇编)

    .data
    float_1: .float -0.5
    float_2: .float 0.0
    float_3: .float 3.1875
    .text
    main:
    	 lw $t1,float_1
    	 lw $t2,float_2
    	 lw $t3,float_3
    		
    

    结果如下:
    在这里插入图片描述
    结果分析:

    • -0.5, 是负数所以第一位为1,0.5 = 0.120.1_{2} = 1.02(2)11.0*2^{-1}_{(2)}. 所以它的指数部分应该是-1+127 = 126 = 01111110201111110_2,尾数1.0,隐藏1,最终结果和上面的一致。
    • 0,符号位0和1都行,只要指数和尾数部分都为0即可。
    • 3.1875 化成二进制就是11.0011211.0011_2(十进制浮点数化为二进制),然后科学计数法表示为1.1001121.10011_2*212^{1},这样指数部分为1,1+127 = 128,华为二进制就是10000000210000000_2尾数部分去掉隐藏的1,就是10011210011_2,上面显示时,t3要比t1少一位,这是因为t3是正数,显示时省略了符号位0。

    1. 具体可以看这本书计算机组成与设计这里面第三章有一部分讲的是浮点表示很有用。 ↩︎

    展开全文
  • 这个涉及到浮点数的结构(符号...2.指数部分有偏移量(float为127,double1023) 3.规格化的表示小数点左边一定1.(二进制数) 4.float类型符号位占1位,指数部分占8位,尾数占23位(因为规格化表示,小数点左边...

    这个涉及到浮点数的结构(符号位,指数部分,尾数部分),以及规格化的表示和非规格化的表示。
    这里不详细解释,LZ可查阅相关资料
    有几个知识点:
      1.计算机中浮点数的基数是2.
      2.指数部分有偏移量(float为127, double为1023)
      3.规格化的表示小数点左边一定为1.(二进制数)
      4.float类型 符号位占1位,指数部分占8位,尾数占23位(因为规格化表示,小数点左边一定为1,所以实际有24位精度)
      5.double类型 符号位占1位,指数部分占11位,尾数占52位(因为规格化表示,小数点左边一定为1,所以实际有53位精度)


    看一个例子float 0.6吧:
    第一步,把十进制转2进制:
     0.6的二进制表示(乘2取整,顺序表示):
       .1001 1001 1001 1001 1001 1001 1001 ... 无限循环下去。

    第二步,计算尾数部分:
     把.1001 1001 1001 1001 1001 1001 1001 ...规格化表示(小数点移到第一个非0书右边)就是:
       1.001 1001 1001 1001 1001 1001 1001 ...,右移了1位。
     由于规格化表示的数小数点左边一定为1,把这个1舍弃,并保留float尾数能表示的23位,最终尾数部分是:
       001 1001 1001 1001 1001 1001

    第三步,计算指数部分: 
     由于计算尾数时右移了1位,相当于乘以2的负1次,所以指数为-1,加上float偏移量127,最后指数为126,
     二进制表示为 0111 1110

    第四步,符号部分:
     0.6为正数,符号位为0

    最终0.6在计算机中的表示就是:

     符号位    指数              尾数
       0    0111 1110  001 1001 1001 1001 1001 1001
    --------------------------------------------------------------
    我们再从这个2进制来计算10进制数:(2的指数次 * 尾数)
     符号位0--> 为正
     指数 0111 1110:为126, 减去偏移量127,结果为-1.
     尾数 001 1001 1001 1001 1001 1001: 规格化的时候小数点左边人掉了一个1,现在加上:
        1.001 1001 1001 1001 1001 1001,转为10进制就是:
        1*2^0 + 1*2^-3 + 1*2^-4 + .....= 1.19999992847442626953125
    1.19999992847442626953125 * 2^-1 = 0.599999964237213134765625
    所以最终结果是一个无限接近于0.6而不能精确表示0.6

    具体更详细的解释和相关知识点,可以自行查阅以及参考收藏中的相关文章介绍

     

    展开全文
  • 背景:float 底层用4个字节32位来表示,为什么范围比int,long还要?  整数在计算机底层采用补码的形式表示,除去首位的符号位,剩余的位数即表示数值的范围,也就是位数越多,范围,那么对于单精度浮点数...

    背景:float 底层用4个字节32位来表示,为什么范围比int,long还要大?

       整数在计算机底层采用补码的形式表示,除去首位的符号位,剩余的位数即表示数值的范围,也就是位数越多,范围越大,那么对于单精度浮点数float,和双精度浮点数double,它们底层的数据结构是什么,它们的范围又是如何计算的,它们的精度范围又是多少那,接下来将从6方面进行阐述。

    1  IEEE754浮点数标准

    IEEE754标准包含一组实数的二进制表示法。它有三部分组成:

    • 符号位
    • 指数位
    • 尾数位

    三种精度的浮点数各个部分位数如下:

    用float来举例:

     

    第一部分用来存储符号位(sign)用来区分正负数0正1负。

    第二部分用来存储指数(exponent)指数也有正负之分,指数位确定大小范围。

    第三部分用来存储小数(fraction),小数位决定了计算精度,因为小数位能表示的数越大,精度越大,数值越准确。

    备注:浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”

    2 第二部分(指数位确定范围)

        需要注意的是指数可能是负数,也有可能是正数,即指数是有符号整数,而有符号整数的计算是比无符号整数麻烦的。所以为了减少不必要的麻烦,在实际存储指数的时候,需要把指数转换成无符号整数

    那么怎么转换呢?注意到float的指数部分是8位,则指数的取值范围是 -126到+127,为了消除负数带来的实际计算上的影响(比如比较大小,加减法等),可以在实际存储的时候,给指数做一个简单的映射,加上一个偏移量,比如float的指数偏移量为127,对应的double类型,存储的时候指数偏移量是1023,这样就不会有负数出现了

    3 第三部分(小数位确定精度)

      float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。
    float:2^23 = 8388608,一共七位,由于最左为1的一位省略了,这意味着最多能表示8位数,但绝对能保证的为7位,也即float的精度为7~8位有效数字(算上整数的一位),不算整数位的话能只有7位,所以能准确表示的10进制也就6位。
    double:2^52 = 4503599627370496,一共16位,同理,double的精度为16~17位,能准确表示的10进制也就15位。

    4 注意点

    • 程序中应尽量避免浮点数的比较,例如System.out.println(2.00-1.10==0.90),永远返回false.
    • float、double类型的运算往往都不准确

    5 正确的方式

    •   利用整数来表示小数int或者long,例如1.01元,则可以以分为单位来表示。
    • 利用BigDecimal进行浮点型运算,但是注意一定要使用String类型的构造方法,如果使用浮点型构造方法也不能得到准确的结果。

    6 福利彩蛋(浮点数保留2位的几种方法)

         1> double dd = (double) (Math.round(1/(float)num*100)/100.0); //先乘以100后除以100,对浮点数做进位处理。

         2> DecimalFormat       df=new DecimalFormat("###.00")

          3>String ss = String.format("%1.2f", 1.1256); 

          4> NumberFormat ddf1=NumberFormat.getNumberInstance() ; ddf1.setMaximumFractionDigits(2);

          5> BigDecimal b = new BigDecimal(T); T = b.setScale(2,BigDecimal.ROUND_HALF_UP).floatValue();

      
    ​​​​​​​
    
    ​​​​​​​
          
    展开全文
  • 进行混合运算的时候 byte short char 不会相互转换 都会自动提升为int 取值范围大小如下 char < int < long < float <double double的取值范围最大 float的取值范围大于long 虽然 long的长度8个...
  • long与float的取值范围谁小

    千次阅读 2019-04-11 23:52:49
    进行混合运算的时候,byte、short、char不会相互转换,都会自动提升为int类型,其他类型进行混合运算是小数据类型提升为大数据类型。...为什么float比long的范围大呢?用一段代码看一下 通过代码可以看出,long类...
  • 我起初的疑问,float取值范围比int取值范围大为什么会出现精度损失那? 这里主要还是int和float底层的存储结构不同导致的。 int使用31位表示精度,float底层有23位来表示尾数,8位表示阶数。 这里精度主要是由这23...
  • 或许大家在刚接触时都会有疑问 虽然int类型与float类型的存储字节大小都是4字节,而且float的取值范围比int为什么int类型转换为float类型是会发生精度缺失? 这要先从float类型的存储方式说起。 float在内存中...
  • 为什么float占4个字节,而long占8个字节,float表示的范围long要得多呢? 原因简单说是因为二者存储的模式不同,long类型是是直接用64位二进制位去存储数据的二进制原码,而float作为浮点数类型,在java里遵循IEEE...
  • Float计算机表示形式

    2019-07-07 01:44:00
    float为什么比int表示的...java中int占用4个字节,float也是占用4个字节,但是为什么float表示的范围比int大呢,因为两者在计算机内中表示的方式不一样,int是4个字节32位,每一位都是二进制小数表示,最高位0代表...
  • 文章目录正文简单的区分自动装箱 / 自动拆箱原始数据类型包装类补充为什么一个字节的范围是-128~127,而不是-127~127?Java 对象要原始数据类型开销的多。你知道对象的内存结构是什么样的吗?比如,对象头的...
  • 浅谈float和double

    2020-04-25 17:56:46
    都知道intfloat在Java中所占的字节数都是4字节,但是int只能存储整数型,float不仅能储存浮点型,存储范围整数,既然同样的字节数为什么会有不同的效果呢? 是因为float和double类型在计算机中的存储结构...
  • float浮点运算

    千次阅读 2013-09-09 14:27:56
    有些C语言书上说float型的有效位数是6~7位,为什么不是6位或者7位?而是一个变化的6~7位?... float浮点数要同为4字节的int定点数表示的范围大的多,那么是否可以使用浮点数替代定点数?  为什么flo
  • 都知道intfloat在Java中所占的字节数都是4字节,但是int只能存储整数型,float不仅能储存浮点型,存储范围整数,既然同样的字节数为什么会有不同的效果呢?是因为float和double类型在计算机中的存储结构和...
  • 浮点数

    2017-11-20 22:19:39
    浮点数的转换1.将浮点数转换成二进制2.用科学技术法表示二进制浮点数3.计算指数偏移后的值注意:计算指数偏移后的值...1029float和int在内存中都占4个字节,为什么float比int所表示的范围大很多?1.float所表示...
  • 浮点数表示问题

    2019-09-05 15:46:38
    关于为什么相同位数 ,int 精度范围更高,float表示范围的问题? 答: int32 在内存中的分配是:1bit(符号位)31bits(实际数字位) float 在内存中的分配情况是:1bit(符号位) 8bits(指数位) 23bits(尾数...
  • 这里是对应java基础及面试题(1.0)的重要面试题 ...long到float不用强转,因为float表示的范围确实long表示的范围大,虽然它只占4个字节,而long占8个字节,float是用科学记数法来表示数据的,long是用二进
  • c浮点数运算

    千次阅读 2017-09-25 22:24:47
     有些C语言书上说float型的有效位数是6~7位,为什么不是6位或者7位?...float浮点数要同为4字节的int定点数表示的范围大的多,那么是否可以使用浮点数替代定点数? 为什么float型浮点数9.87654321 > 9
  • 浮点数运算

    千次阅读 2015-05-26 14:49:58
    float浮点数要同为4字节的int定点数表示的范围大的多,那么是否可以使用浮点数替代定点数? 为什么float型浮点数9.87654321 > 9.87654322不成立?为何10.2 - 9的结果不是1.2,而是1.1999998?为何98765
  • 前言  有些C语言书上说float型的有效位数是6~7位... float浮点数要同为4字节的int定点数表示的范围大的多,那么是否可以使用浮点数替代定点数?  为什么float型浮点数9.87654321 > 9.87654322不成立?为何10.2 -
  • C语言浮点数解惑

    千次阅读 2013-08-12 19:15:49
    前言  有些C语言书上说float型的有效位数是6~7位,... float浮点数要同为4字节的int定点数表示的范围大的多,那么是否可以使用浮点数替代定点数?  为什么float型浮点数9.87654321 > 9.87654322不成立?为何10.2 -
  • 为什么double型数据范围long型范围大,因为double型数据是按照特别格式存储数据的) 自动数据类型提升 byte -->short ==char -->int–>long–>float–>double 在基本数据类型的表达式运算中...
  • 有些C语言书上说float型的有效... float浮点数要同为4字节的int定点数表示的范围大的多,那么是否可以使用浮点数替代定点数?  为什么float型浮点数9.87654321 > 9.87654322不成立?为何10.2 - 9的结果不是1.2,而
  • C语言浮点数运算

    2012-05-22 19:32:00
    float浮点数要同为4字节的int定点数表示的范围大的多,那么是否可以使用浮点数替代定点数? 为什么float型浮点数9.87654321 > 9.87654322不成立?为何10.2 - 9的结果不是1.2,而是1.1999998?为何987654321 + ...
  • Java语法基础学习DayTwo

    2019-02-26 17:40:00
    一、数据类型补充问题 数据类型的自动转换等级: byte,short,char -- int -- long -- ...float表示的数据范围比long要。 二、运算符 1.算术运算符+,-,*,/,%,++,-- %:任何整数模2不是0就是1,所以只要改变被...

空空如也

空空如也

1 2 3
收藏数 49
精华内容 19
关键字:

为什么float比int范围大