java中的基本数据类型存储的范围原理解释总结

首先呢,我先将结果给大家以表格的形式表现出来,原因呢我下面会解释。

数据类型 字节长度 表示范围(二进制形式) 表示范围(数值)
 byte(字节型) 1 10000000~01111111 -128(-2^7)~127(2^7-1)
short(短整型) 2 10000...0000(后面15个0)~0111111111....111111(后面15个1) -32768(-2^15)~23767(2^15-1)
int(整型) 4 10000...0000(后面31个0)~0111111111....111111(后面31个1) -2147483648(-2^31)~2147483647(2^31-1)
long(长整形) 8 10000...0000(后面63个0)~0111111111....111111(后面63个1) -9223372036854775808(-2^63)~9223372036854775807(2^63-1)
float(单精度) 4 1 01111111 1111...11111 (后面23个1)~001111111 1111...11111 (后面23个1) -3.4028235E38(-2*2^127)~3.4028235E38(2*2^127)
double(双精度) 8 1 01111111111  11111...1111(后面共52个1)~0 01111111111  11111...1111(后面共52个1) -1.7976931348623157E308(-2*2^1023)   ~1.7976931348623157E308(2*2^1023)
char(字符型) 2 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111           0    -   65535(2^16-1)








(无穷没有表示)


(无穷没有表示)

 (无符号i)


壹:

就以byte为例介绍:(整数方面事符号位:    0正1负)

<1>byte   1个字节 ,所以说就有8位二进制代码  

<2>_ _ __ ____ 横线代表一个位,因为规定最高位是符号位,所以说最大的数用二进制表示就为 0111 1111

   ( 2^0+2^1+2^2+2^3+2^4+2^5+2^6 = 2^7-1)

<3>同样不难理解,byte类型最小的数自然就是1 0 0 0   0 0 0 0       (也是一种规定,关于补码溢出的)                 ( -2^7)

“这里需要知道,对于二进制的负数在计算机中的存储是以补码的形式存在的,也就是说,在计算机中看到的负数的二进制不是其真正的二进制是其补码的二进制表示”

<4>总体而言,byte的范围是有 256(2^8)个数,因为是有8位所以就是2的8次,java分为正负的两部分所以上面的就是2 的7次,有0的话所以正数的绝对值比负数的绝对值少1

<5>其他的类型与byte相同,原理一样,其他语言的原理也一样

贰:

以float为例讲一下,关于float的存储范围的问题,java中对于实数(浮点数)的存储是在二进制的位数上存储了指数部分

<1>  flaot的存储示意图


(图片来自于Quora)

sign 代表符号位 1 代表负数 0代表正数;    exponent  代表指数位  最大为127 ,和byte有一点点联系   其中第30位(0代表指数为 1 为正);

fraction 代表小数位,共有23位实际上表示24位,第24位唯一 是1  ,所以表示的小数就是  1.   ..........

  

                                       31                       30                  29----23               22----0         

                        表示实数符号位        指数符号位           指数位             有效数位(就是科学记数法的前面的那个有小数点的数)


<2> 将一个float型转化为内存存储格式的步骤为:

     (1)先将这个实数的绝对值化为二进制格式,注意实数的整数部分和小数部分的二进制方法在上面已经探讨过了。 
     (2)将这个二进制格式实数的小数点左移或右移n位,直到小数点移动到第一个有效数字的右边。 
     (3)从小数点右边第一位开始数出二十三位数字放入第22到第0位。 
     (4)如果实数是正的,则在第31位放入“0”,否则放入“1”。 
     (5)如果n 是左移得到的,说明指数是正的,第30位放入“1”。如果n是右移得到的或n=0,则第30位放入“0”。 
     (6)如果n是左移得到的,则将n减去1后化为二进制,并在左边加“0”补足七位,放入第29到第23位。如果n是右移得到的或n=0,则将n化为二进制后在左边加“0”补足七位,再各位求反,再放入第29到第23位。

 

          举例说明: 11.9的内存存储格式

       (1) 将11.9化为二进制后大约是" 1011. 1110011001100110011001100..."。

       (2) 将小数点左移三位到第一个有效位右侧: "1. 011 11100110011001100110 "。 保证有效位数24位,右侧多余的截取(误差在这里产生了 )。

       (3) 这已经有了二十四位有效数字,将最左边一位“1”去掉,得到“ 011 11100110011001100110 ”共23bit。将它放入float存储结构的第22到第0位。

       (4) 因为11.9是正数,因此在第31位实数符号位放入“0”。

       (5) 由于我们把小数点左移,因此在第30位指数符号位放入“1”。

       (6) 因为我们是把小数点左移3位,因此将3减去1得2,化为二进制,并补足7位得到0000010,放入第29到第23位。

 

           最后表示11.9为:  0 1 0000010 011 11100110011001100110

 

           再举一个例子:0.2356的内存存储格式
      (1)将0.2356化为二进制后大约是0.00111100010100000100100000。 
      (2)将小数点右移三位得到1.11100010100000100100000。 
      (3)从小数点右边数出二十三位有效数字,即11100010100000100100000放
入第22到第0位。 
      (4)由于0.2356是正的,所以在第31位放入“0”。 
      (5)由于我们把小数点右移了,所以在第30位放入“0”。 
      (6)因为小数点被右移了3位,所以将3化为二进制,在左边补“0”补足七
位,得到0000011,各位取反,得到1111100,放入第29到第23位。 
       

           最后表示0.2356为:   0 0 1111100 11100010100000100100000



<3>对于最后的值有一个计算的公式:

float的值 = (1)S(2E127)(1.M)

S代表符号

E代表指数

M代表有效小数部分

float类的指数是8位移码,最大为127最小为-126,

(23-30位共8位为指数位,这里指数的底数规定为2(取值范围:0~255)。这一部分的最终结果格式为:2E127,即范围-127~128。另外,标准中,还规定了,当指数位8位全0或全1的时候,浮点数为非正规形式(这个时候尾数不一样了),所以指数位真正范围为:-126~127。)

127用来作2的指数,为2^127,约等于 1.7014*10^38, 而我们知道,floa示数范围约为- 3.4*10^38-------3.4*10^38, 这是因为尾数都为1时,即1.11..11约为2,因此浮点数的范围就出来了.

<4>double与float类似,原理一样,只不过

   符号位(S):1bit    指数位(E):11bit    尾数位(M):52bit

double的值 = (1)S(2E1023)(1.M)

叁:

char类型是用两个字节来表示,使用的是Unicode编码,所以可以正常表示中文字符。两个字节一共十六位,又因为没有符号位,都是数值位的原因,所以表值范围是从:0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111 (65535)

所以char类型的表值范围是从 0 ~ 2^16-1


注意:以上是经查验许多资料得出的,也有引用一些觉得写的好的话语句,有不详细或者错误的地方,还请斧正。。

你可能感兴趣的:(java)