Java中的基本数据类型

数值型

byte1字节
short char2字节
int4字节
long8字节
float4字节
double8字节

非数值型

boolean

注意:

  1. 这8种数据类型都是Java的基本数据类型,值得注意的是Java中的int与float字节数相同,但是表示方法不同,从而范围不同, float采用科学计数法
  2. char类型是数值型中唯一一个无符号位的数据类型,而其他数据类型中,使用二进制对其进行表示的时候,最开始的一位便是符号位,1为负数 0 为正数
  3. 虽然0000 0000 与 1000 0000 都可以代表0,但是计算机中采用补码来表示0
  4. short与char 的字节数相同,但是因为char无符号位,因此char: 0-65535 short:-32768-32767

Java的基本类型数据转换注意事项

Java中对于数据类型的转换,有着默认的规则,这里将记录一些常用的套路,对于更深层次的研究,请移步

  1. 小类型转换成大类型自动转换,大类型转换成小类型需要进行强转(可能会产生溢出)
  2. 当数据类型所表示的范围无大小之分时,产生精度损失就需要进行强转(例如char和int类型进行转换)
  3. int以及int类型以下的数据类型运算结果为int
  4. char类型是数值型中唯一一个没有符号位的数据类型,同时char类型在定义的时候还可以用单个字符来进行定义
  5. 大类型 + 小类型 = 大类型
  6. float以及double 都采用科学计数法来表示一个数字,虽然float和int所占用字节数相同,long和double所占字节数相同,但是两者表示方法不同,从而所表示的数值范围不同。Java中的小数类型默认是double类型
  7. char类型数据可以转换为任意一个数据类型,但是将整数转换为一个char类型的时候,只用到该整数的低16位,其余被忽略。
  8. 将一个浮点型数转换为一个char类型的数字的时候,首先将浮点型数值转换成int类型,然后转换为char类型。如果转换结果适用于目标变量,则隐式转换,否则显式转换
  9. 所有数值操作符都可以用在char类型操作数上,如果另一个操作数是一个数字或字符,那么char类型操作数就会被自动转换成一个数字,如果另一个操作数是一个字符串,字符就会与该字符串相连。

Java一些语句的注意事项

当采用记事本编程Java的时候,需要使用ctrl + c 退出dos下的死循环,然后dos下键入cls清屏

  1. switch语句中,条件只能是int以及int一下的数据类型,从JDK1.7开始支持字符串
  2. switch语句执行,每个case语句一旦触发,没有break时,后面的语句都会得到执行
  3. Java中 + 号作为被重载的运算符具有两个功能: 第一,如果+号两边都是数字,则计算结果为数字。第二,如果+号两边,出现字符串,则会对字符串进行拼接。

float内存详解

这里将会介绍一些float的内存详解,用来区分int与float,从而更深层次的理解int 与 float为什么会字节数相同,表示的数据类型范围不同,不仅仅是体现在了方法上面

表示方法

  1. 定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。
  2. 计算机系统采纳了所谓的浮点数表达方式。这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa也叫有效数字 ),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。
  3. 当一个浮点数的尾数为0,不论其阶码为何值,该浮点数的值都为0。当阶码的值为它能表示的最小一个值或更小的值时,不管其尾数为何值,计算机都把该浮点数看成零值,通常称其为机器零,此时该浮点数的所有各位(包括阶码位和尾数位)都清为0值。

Java 平台上的浮点数类型 float 和 double 采纳了 IEEE 754 标准中所定义的单精度 32 位浮点数和双精度 64 位浮点数的格式。
在 IEEE 标准中,浮点数是将特定长度的连续字节的所有二进制位分割为特定宽度的符号域,指数域和尾数域三个域,其中保存的值分别用于表示给定二进制浮点数中的符号,指数和尾数。这样,通过尾数和可以调节的指数就可以表达给定的数值了。

表示原理讲解

  1. 第一个域为符号域。其中 0 表示数值为正数,而 1 则表示负数。
  2. 第二个域为指数域,对应于我们之前介绍的二进制科学计数法中的指数部分。其中单精度数为 8 位,双精度数为 11 位。以单精度数为例,8 位的指数为可以表达 0 到 255 之间的 255 个指数值(注:指数8位的最高位都是数值位,没有符号位)。但是,指数可以为正数,也可以为负数。为了处理负指数的情况,实际的指数值按要求需要加上一个偏差(Bias)值作为保存在指数域中的值,单精度数的偏差值为 127(2^7-1),而双精度数的偏差值为1023(2^10-1)。比如,单精度的实际指数值 0 在指数域中将保存为 127;而保存在指数域中的 64 则表示实际的指数值 -63(64-127=-63)。 偏差的引入使得对于单精度数,实际可以表达的指数值的范围就变成 -127(表示小数点需向左移动127位) 到128(表示小数点需向右移动128位) 之间(包含两端)。我们不久还将看到,实际的指数值 -127(全 0)以及 +128(全 1)保留用作特殊值的处理。这样,实际可以表达的有效指数范围就在 -127 和 127 之间。
  3. 第三个域为尾数域,其中单精度数为 23 位长,双精度数为 52 位长。除了我们将要讲到的某些特殊值外,IEEE 标准要求浮点数必须是规范的。这意味着尾数的小数点左侧必须为1,因此我们在保存尾数的时候,可以省略小数点前面这个 1,从而腾出一个二进制位来保存更多的尾数。这样我们实际上用 23 位长的尾数域表达了 24 位的尾数。比如对于单精度数而言,二进制的 1001.101(对应于十进制的 9.625)可以表达为 1.001101 × 2^3,所以实际保存在尾数域中的值为 00110100000000000000000,即去掉小数点左侧的 1,并用 0 在右侧补齐。
注意

值得注意的是,对于单精度数,由于我们只有 24 位的尾数(其中一位隐藏),所以可以表达的最大尾数为 2^24- 1 = 16,777,215。特别的,16,777,216 是偶数,所以我们可以通过将它除以 2 并相应地调整指数来保存这个数,这样 16,777,216 同样可以被精确的保存。相反,数值 16,777,217 则无法被精确的保存。由此,我们可以看到单精度的浮点数可以表达的十进制数值中,真正有效的数字不高于 8 位。事实上,对相对误差的数值分析结果显示有效的精度大约为 7.22 位(由于位数不可取小数,所以单精度的精度为7,即可精确到小数点后7位)。参考下面的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
System.out.println(16777215f);/*1.6777215E7  */
System.out.println(16777216f);/*1.6777216E7 */
System.out.println(16777217f);/*1.6777216E7 */
System.out.println(16777218f);/*1.6777218E7 */
System.out.println(16777219f);/*1.677722E7 */
System.out.println(16777220f);/*1.677722E7 */
System.out.println(16777221f);/*1.677722E7 */
System.out.println(16777222f);/*1.6777222E7 */
System.out.println(16777223f);/*1.6777224E7 */
System.out.println(16777224f);/*1.6777224E7 */
System.out.println(16777225f);/*1.6777224E7 */
System.out.println(16777215f);/*1.6777215E7*/
System.out.println(16777216f);/*1.6777216E7*/
System.out.println(16777217f);/*1.6777216E7*/
System.out.println(16777218f);/*1.6777218E7*/
System.out.println(16777219f);/*1.677722E7*/
System.out.println(16777220f);/*1.677722E7*/
System.out.println(16777221f);/*1.677722E7*/
System.out.println(16777222f);/*1.6777222E7*/
System.out.println(16777223f);/*1.6777224E7*/
System.out.println(16777224f);/*1.6777224E7*/
System.out.println(16777225f);/*1.6777224E7*/

请看结果推导分析:

111111111111111111111111 16777215f
1.11111111111111111111111 刚好是23位,不会丢失精度,能精确表示 0 23+127 11111111111111111111111 0 10010110 11111111111111111111111

1000000000000000000000000 16777216f
1.00000000000000000000000 0 去掉的是0,所以还是能准确表示 0 24+127 00000000000000000000000 0 10010111 00000000000000000000000

1000000000000000000000001 16777217f
1.00000000000000000000000 1 不能准确表示。先试着进位
1.00000000000000000000001 由于进位后,结果的最末们不是0,所以直接舍掉
1.00000000000000000000000 到这里结果就是16777216f

1000000000000000000000010 16777218f
1.0000000000000000000001 0 去掉的是0,所以还是能准确表示 0 24+127 00000000000000000000001 0 10010111 00000000000000000000001

1000000000000000000000011 16777219f
1.0000000000000000000001 1 不能准确表示。先试着进位
1.0000000000000000000010 进位后的结果,最末们为0,所以进位成功 0 24+127 00000000000000000000010 0 10010111 00000000000000000000010
1.000000000000000000000100*2^24 16777219f存储在内存中的结