详细讲解int、float与double的区别

最近为了看一下float的精确度仔细看了一下这三种数据在内存中的样子,看了一下别人的博客发现大家对精度都有这不同的定义,我自己也简单画了一下。

下面来主要讲解一下int、float与double三者的区别与详解

一、int(最简单的一种)

int数据类型在内存中占用了4个字节byte(4*8个bit比特)就是32个比特位。第一位代表int的正负,后31位存储数据。当int取最大值时相当于31个1(1*2^30+1*2^29+1*2^28+....+1*2^0)可以转化为有32位切为1其他为0之后再减去1(1*2^31-1)。换算一下大概是21亿多。

二、float(单精度浮点型数据)

在说float之前先说一下二进制与十进制的小数部分的转化。

  • 小数十进制转二进制:十进制的小数每次*2取整数部分的值作为当前的位数上的值。例如0.25:0.25*2=0.5(整数部分为0,二进制第一位为0),0.5*2=1.0(整数部分为1切小数为0不继续了,二进制第二位为1)得出0.25用二进制表示为0.01。

  • 小数二进制转十进制:与整数类似,当前位置*2的负数次方。例如0.01=0*2^0+0*2^-1+1*2^-2=0+0+1/4=0.25

float与int一样都占了四个字节也就是32个比特位,但是存储的含义与int不一样了。其中第一位代表正负,第2-9这八位代表指数,与后23位的底数。

如图为单精度存储方式:

 

  • 符号位(1bit):0位正数,1位负数。

  • 指数位(8bit):用于记录科学计数法中指数数据(由于指数也有正负,所以实际能表示指数的只有7位为-127-128,所以指数部分采用移位存储,存储的数据+127。之前的存储可以理解成01111111代表128,11111111代表-127。采用移位存储之后。这样8位就没有正负之分,00000000代表-127,11111111代表128)。由于指数位全为1的时候有特殊用途(暂时不知道有什么含义),所以指数位真正的取值范围是-127-127。

  • 尾数位(底数位)(23bit):记录科学计数法中的底数部分。

任何一个二进制的科学计数法都可以写成1.xxxxx*2^n,这里的n就是指数位,而尾数最小位00000000000000000000001转化为十进制为0.0000001192092896,但是由于位数变化不足以覆盖0.0000001-0.0000009(00000000000000000000101为5而00000000000000000000110为7所以0.0000006无法表示精度丢失一个)但足以覆盖0.000001-0.000009。所以说float的精度为6-7位(十进制小数点后位数)

例如:8.25转化为二进制时候为1000.01,转化成二进制的科学计数法为1.00001*2^3。所以转化为float在内存中存储的时候为:符号位为0,指数位为(3+127)1000 0010,尾数位为(0.00001)000 0100 0000 0000 0000 0000 最终8.25存储为float的形式为:(0 10000010 00001000000000000000000)

所以float的最大值为1.11111111111111111111111*2^127(科学计数法)= 127个全1的二进制减去一个103个全1的二进制 =

(2^128-1)-(2^104-1)=3.4028234663852886*10^38=3.40282e+038

三、double(双精度浮点型数据)

double占了8个字节,也就是64bit。

  • 符号位(1bit):0位正数,1位负数。

  • 指数位(11bit):指数范围为2^10(-1023-1024)

  • 尾数位(底数位)(52bit):记录科学计数法中的底数部分。

double数据基本与float一致,最大值是1023个全1的二进制减去一个973个全1的二进制=(2^1024-1)-(2^974-1)=1.79769e+308

你可能感兴趣的:(随笔,java,float,double,int)