数值分为整型和浮点型两大块。不管是哪种类型,在计算机中都是按二进制形式存储,只有0 和1 两种符号。基本数据类型byte 、short 、int 、long 、float 、double 。常量有整型、浮点型和字符串。整型常量不加后缀符号代表int 类型,浮点型常量不加后缀符号表示double 类型。
整型的保存形式
一个32位整数存储形式如下:
++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 0 1 1 0 0 0 1 ++ 0 1 0 0 1 1 1 1 ++ 1 0 1 1 0 0 0 1 ++ 0 1 0 0 1 1 1 1 +
++++++++++++++++++++++++++++++++++++++++++++++++
在存储有符号整型int 时,将最高位的二进制数作为符号位,0 代表整数,1 代表复数。剩余可表示数值的位数只剩下31位。有符号整型在保存形式上与人类有点普通,下面做了一个尝试:
int
人为去计算1288457420的二进制表示形式,是01001100110011000100110011001100;而 -1288457420的二进制表示形式,猜测是11001100110011000100110011001100。但是实际的结果是:
//
有这样三个名词:原码、反码、补码。正数原码等于补码,负数补码等于原码不带符号位取反再加一。
补码这个词在我印象中一直有个误区:“在负数参与运算时,才会进行原码转换补码的转换操作从而实现加法操作”。但是其实并不是。补码是数值在计算机中的保存形式,在计算机中数值一直就是补码形式,比如上面定义的负数i 。原码这个词,在计算机中并不存在,只是人类在计算补码形式所创建的一个临时的形式,计算机并不认识它。下面再做另一个测试:
int
以“我们所认为的原码形式”的二进制常量去定义一个整型i ,输出二进制形式和十进制形式,于是我们按原码转十进制的方法计算得到了二进制数 -1288457420。但是实际的结果:
11001100110011000100110011001100
可以发现保存的十进制数和我们预想的不太一样,它直接将“我们所认为的原码形式”理解为补码形式。这再一次证明了,计算机中并不存在所谓的原码,二进制形式一律是补码形式,本例中,0b11001100110011000100110011001100也被计算机理解为补码形式,于是我们将补码取反加一求得原码,即可得到实际的十进制结果 -859026228
整型间的类型转换
按byte 、short 、int 、long 的顺序,类型所表示的范围是递增的。从低到高允许自动转换。
byte
不同类型的变量从高向低进行转换必须使用强制转换。
long
从高到低转换会丢失精度,计算机会截断高位的全部数据,毕竟越低的类型能表示的范围就越小。从long向int转换,高32位的01111111111111111111111111111111全部被舍弃,只剩低32位的11111111111111111111111111111111,最高位的1 被作为符号位。由于计算机中二进制的表示形式为补码形式,转换为原码形式就是-1 。继续往更低的类型也是一样的道理。
整型常量向非整型变量进行类型转换,在常量值不超过该变量能表示的范围的情况下可以自动转换,否则必须加强制转换。比如int向short转换,int向byte转换:
short
但非整型常量就没有这样的待遇:
int
编译器在进行运算时只有两种精度可选32位和64位。小于等于32位的类型运算时都会得到32位整型的结果,然后再判断其值是否超过该类型能表示的最大范围,超过则可以自动转换,不会编译错误,否则必须添加强制转换;如果使用变量运算,编译器无法确定运算结果,必须添加强制转换。以下以byte类型为例:
byte
小于32位精度的short类型也是一样的道理。赋值运算符不必加上强制转换,赋值运算符的右侧在编译时会自动添加强制转换符号。
byte
浮点型的表示形式
后面再了解