事先申明,本文为菜鸡笔者自己学习总结,大佬若觉得笔者说的是废话可自行忽略,如果觉得笔者写的还凑合也请指正其中不对之处,笔者在此感谢。相信搞Java的或正在学java的都应该见过下面这个表格:
数据类型 | 关键字 | 内存占用 | 取值范围 |
---|---|---|---|
字节型 | byte | 1个字节 | -128 ~ 127 |
短整型 | short | 2个字节 | -32768 ~ 32767 |
整型 | int | 4个字节 | -231 ~ 231-1 |
长整型 | long | 8个字节 | -263 ~ 263-1 |
单精度浮点型 | float | 4个字节 | 1.4013 x 10-45 ~ 3.4028 x 1038 |
双精度浮点型 | double | 8个字节 | 4.9 x 10-324 ~ 1.7977 x 10308 |
字符型 | char | 2个字节 | 0 ~ 65535 |
布尔型 | boolean | 1个字节 | true , false |
本文要说明的就是这些取值范围是怎么通过数据类型的内存占用计算而来的,其中浮点型部由于未找到合适的资料说明故存在一定猜测成分,望大佬指正。
首先是整数类型:
整数类包含字节型,短整型,整型,长整型4种,而这4种类型均采用补码形式编码,比如字节型byte占1字节也就是8位,那么8位补码能表示的数据范围即为byte的取值范围即-128 ~ 127,至于为什么补码负数能比正数多表示一个,可以参考我的这篇博客 文章链接。
再是浮点数类型:
浮点数类型如何编码可参考笔者得这篇博文 文章链接,上表给出得浮点数范围为浮点数正数得范围,负数范围同理,只是符号位转变了而已,以float为例,float表示的最大正数为(7f7fffff)16 = (0111 1111 0111 1111 1111 1111 1111 1111) 2,符号位 S = 0 表示正数,阶码 E = 11111110,尾数M为:111 1111 1111 1111 1111(1-2-23),至于阶码为什么取11111110 (254) 而不是11111111(255),是因为阶码255在IEEE754标准里被拖去做特殊值处理用了,下文也会做说明。故可以计算到float表示的最大值为:(-1)S x 1.M x 2E-127=(1 + 1 - 2-23) x 2127= 3.4028234663853 x 1038,即上表float的正数范围上界。
再来考虑正数下界,float能表示的最小正数编码为(00000001)16 = (0000 0000 0000 0000 0000 0000 0000 0001)2,符号位 S = 0,阶码 E = 00000000, 尾数M为:000 0000 0000 0000 0001,按照公式:(-1)S x 1.M x 2E-127=(1+2-23) x 2-127 = 5.8774724547607 x 10-39 。
???欸,怎么和上表对不上,你是不是有这样的疑问?其实。。。对不上肯定是错了呗 < _ < ||,那么问题来了,哪里错了,然后笔者就开始疯狂的百度,然后发现了这篇博文 文章链接,该文章里有一组这样的表:
符号位 | 阶码部分 | 阶码部分-127 | 尾数部分 | 小数部分最高有效位 | 形式 |
---|---|---|---|---|---|
1 | 255 | 128 | 非0 | 没有 | NaN |
1 | 255 | 128 | 0 | 没有 | 负无穷 |
1 | 1~254 | -126~127 | 任意 | 1 | 正规形式(负数) |
1 | 0 | -127 | 非0 | 0 | 非正规形式(负数) |
1 | 0 | -127 | 0 | 没有 | 负0 |
0 | 255 | 128 | 非0 | 没有 | NaN |
0 | 255 | 128 | 0 | 没有 | 正无穷 |
0 | 1~254 | -126~127 | 任意 | 1 | 正规形式(正数) |
0 | 0 | -127 | 非0 | 0 | 非正规形式(正数) |
0 | 0 | -127 | 0 | 没有 | 正0 |
按照这张表,当阶码为0时,尾码部分非0表示应该是非正规形式,小数部分最高有效位为0,这和我在此段开头提到笔者所写的另一篇博文的内容相矛盾 文章链接,这篇文章是笔者依据白中英教授所写的《计算机组成原理》中浮点数表示法的一些总结,在《计算机组成原理》中有一段指出了只要尾码非0有效位就存在且为1,但这张表也是该博主根据iEEE754标准所写,由于笔者水平有限,也没查到更准确的说法,所以姑且按上表的说明继续计算,即没有有效位1,那么小数点现在应该在什么位置呢,假设小数点的位置没动,那么式子就变为:(-1)S x 0.M x 2E-127= 2-23 x 2-127 = 7.0064923216241 x 10-46 , 得!好家伙,还是对不上。。。然后笔者猜想是不是由于编码此时不存在最高有效位,所以小数点也跟着向右移了一位,那么此时式子变为(-1)S x (0.M x 2) x 2E-127 = 2-149 = 1.4012984643248 x 10-45。好家伙,终于对上了。笔者又按此方法验算了双精度double型,也符合最上面那张表给出得范围。但毕竟这个处理方式存在笔者得猜测成分,所以笔者不敢保证一定是对的。综上,如果有在这方面有研究的大佬知道正确结论还请评论区指正,笔者在此感谢!
至于字符型和布尔型:
已经很明显了内存占位2字节,那么能表示的字符数量就和短整型表示的数据大小一致,一个萝卜一个坑放就行了,从 0 ~ 65535。布尔型就俩值true和false,但是字节是数据存储的最小单元,所以至少要开辟一个字节用于存储。