基本数据类型 | 占二进制位数 | 包装类 |
---|---|---|
byte | 8 | Byte |
short | 16 | Short |
int | 32 | Integer |
long | 64 | Long |
float | 32 | Float |
double | 64 | Double |
char | 16 | Character |
boolean | 1(只有true和false两个取值) | Boolean |
long数据类型在给变量赋值时,数据末尾要加L(小写也可以,但是建议大写)以示区分
float数据类型要在末尾加上f
条件判断超预期
System.out.println(0.9999999f==1f);//false System.out.println(0.99999999f==1f);//true
基本计算超预期
System.out.println(0.2+0.7);//0.8999999999999999 System.out.println(0.3+0.6);//0.8999999999999999 System.out.println(0.4+0.5);//0.9
类型转换超预期
float f = 1.2f; double d = (double) f; System.out.println(f);//1.2 System.out.println(d);//1.2000000476837158
数据自增超预期
float f2 = 84552631f; for (int i = 0; i < 5; i++) { System.out.println(f2); f2++; } // 8.4552632E7 // 8.4552632E7 // 8.4552632E7 // 8.4552632E7 // 8.4552632E7
出现这种问题的主要原因浮点数表示字长是有限的,会有舍入误差,接近但不等于
所以如果代码涉及到,货币运算等精度需求高的时候,最好不要使用浮点数。
通过计算机原理,了解了浮点数采用阶码+尾数来表示,类似于数学中的科学计数法,有效数字+指数
单精度浮点数(float):左边第一位表示符号位(S),之后的8位表示阶码位(E),剩下的23位表示尾数位(M)。
双精度浮点数(double):左边第一位表示符号位(S),之后的11位表示阶码位(E),剩下的52位表示尾数位(M)。
阶码位是8位无符号位整数,所以可以表示0~255,由于浮点数存储遵循IEEE 754浮点数技术标准,真值的“指数“存入阶码位是必须要增加一个中间值,0~255的中间值就是127,所以单精度是127,双精度是1023。举个例子,2^10 指数是10,E的值就是10+127=137,也就是10001001。
单精度浮点数的尾数有23位,转换为十进制就是2^23= 8388608,所以十进制的精度是6~7位。
双精度浮点数的尾数有52位,转换为十进制就是2^52=4503599627370496,所以十进制精度是15~16位。
所以浮点数在计算机存储时会出现精度丢失问题。
整数部分除二取余,小数部分乘2取整,最后两者相加就得到了二进制小数。
将二进制小数转换为阶码+尾数形式,然后再转换成为在计算机存储的样子。
注意:
尾数部分的小数,小数点前一位永远是1,可以省略。
小数部分乘2取整时,可能会碰到无限不循环的情况,计算机一定会进行截取,所以一定会出现精度损失,所以在使用浮点数时一定要考虑再三。
int i=128; byte b=(byte)i; System.out.println(b);//输出-128 内存溢出 int money=1_000_00000;//数字之间可以用下划线。 int years=200; int total1=money*years; System.out.println(total1);//输出-1474836480 溢出 long total2=((long)money)*years; System.out.println(total2);//20000000000
注意点
不能对布尔值进行转换
高容量转换成低容量是进行强制转换
类型转换时会出现溢出和精度问题