數據在電腦內部是以二進位形式表示的,而數據有各種各樣的類型(比如數值、文本、日期......),不同類型的數據具有不同的特點,如果按照統一的格式進行處理,會很不方便。 為此,高級語言引入了數據類型的概念,用於對數據進行歸類,以便理解和操作。 數據類型分為基本數據類型和引用(對象)數據類型。其中,基 ...
數據在電腦內部是以二進位形式表示的,而數據有各種各樣的類型(比如數值、文本、日期......),不同類型的數據具有不同的特點,如果按照統一的格式進行處理,會很不方便。
為此,高級語言引入了數據類型的概念,用於對數據進行歸類,以便理解和操作。
數據類型分為基本數據類型和引用(對象)數據類型。其中,基本數據類型相當於化學中的基本元素,引用(對象)數據類型相當於元素組成的世間萬物。
進位
十進位
十進位的位權為 10,如 123 的十進位 123,123 = 1 * (10^2) + 2 * (10^1) + 3 * (10^0)
。
二進位
二進位的位權為 2,如 4 的二進位 100,4 = 1 * (2^2) + 0 *(2^1)+ 0 *(2^0)
。
十進位轉二進位
- 整數部分:除 2 取餘,直到商小於 1 為止,再逆序排列。
-
小數部分:乘 2 取整,直到積的小數部分為零或者達到要求的精度,順序排列。
-
最後將整數部分和小數部分合併即可。
/*
如:0.25 的二進位為 0.01
整數部分:
0 % 2 = 0 取餘 0,小於 1,終止,逆序得 0
小數部分:
0.25 * 2 = 0.50 取整 0
0.50 * 2 = 1.0 取整 1,小數部分為 0,終止,順序得 01
合併:
0.01
*/
二進位轉十進位
使用位權計算。
/*
如:2.25 的二進位為 10.01
2.25 = 1 *(2^1)+ 0 *(2^0)+ 0 *(2^-1)+ 1 *(2^-2)
*/
Java 整數的二進位表示
bit 位:電腦中表示數據的最小單位,就是二進位的一位,可取 0 或 1(電路的開關)。
Java 使用最高位(左邊第一位)表示符號位,符號位為 0 表示正數,為 1 表示負數。
- 原碼,用第一位表示符號,其餘位表示值。
byte beVar1 = 1; // 原碼:0000 0001
byte beVar2 = -1; // 原碼:1000 0001
- 反碼,正數的反碼等於原碼,負數的反碼是原碼的符號位不變,其餘位取反。
byte beVar1 = 1; // 反碼:0000 0001
byte beVar2 = -1; // 反碼:1111 1110
- 補碼,正數的補碼等於原碼,負數的補碼是在反碼的基礎上加 1,補碼取反碼再加 1 又得到原碼。
byte beVar1 = 1; // 補碼:0000 0001
byte beVar2 = -1; // 補碼:1111 1111
Java 小數的二進位表示
二進位中為表示小數,採用類似十進位的科學計數法,幾乎所有的硬體和編程語言表示小數的二進位格式都是使用 IEEE 754 標準。
32 位單精度二進位 = [1 個符號位] [8 個階碼位] [23 個尾數位]
64 位雙精度二進位 = [1 個符號位] [11 個階碼位] [52 個尾數位]
小數 = [符號位] [指數部分] . [小數部分]
8 位階碼位移碼偏移量 127,11 位階碼位移碼偏移量 1023
/*
如:2.25,二進位 10.01,先化為科學計數法 1.001 * (2^1)
32 位單精度表示:
符號位: 0
階碼位:階碼 = 指數 + 階碼位移碼偏移量 = 1 + 127 = 128,二進位 1000 0000
尾數位:尾數 = 取小數點後 23 位,001 0000 0000 0000 0000 0000
最終得:[0][1000 0000][001 0000 0000 0000 0000 0000]
同理可得 -2.25 的二進位:[1][1000 0000][001 0000 0000 0000 0000 0000]
*/
System.out.println(Integer.toBinaryString(Float.floatToIntBits(2.25F)));
System.out.println(Integer.toBinaryString(Float.floatToIntBits(-2.25F)));
基本數據類型
在 Java 中,有如下的基本數據類型。
byte 位元組型
8 bit 位,占 1 個位元組,取值範圍 -2^7 ~ 2^7 - 1,預設值為 0。
byte beVar = 100;
short 短整型
16 bit 位,占 2 個位元組,取值範圍 -2^15 ~ 2^15 - 1,預設值為 0。
short stVar = 200;
int 整型
32 bit 位,占 4 個位元組,取值範圍 -2^31 ~ 2^31 - 1,預設值為 0,整數預設類型。
int itVar = 300;
long 長整型
64 bit 位,占 8 個位元組,取值範圍 -2^63 ~ 2^63 - 1,預設值為 0。
long lgVar1 = 400; // 在 int 型的取值範圍內時可用,不建議,最好加上 L
long lgVar2 = 400L;
float 單精度浮點數
32 bit 位,占 4 個位元組,預設值為 0.0F
,不能用於表示精確值,如貨幣。
float ftVar = 3.14F; // 浮點數預設類型是 double,必須加 F
double 雙精度浮點數
64 bit 位,占 8 個位元組,預設值為 0.0D
,浮點數預設類型,不能用於表示精確值,如貨幣。
double deVar1 = 3.14;
double deVar2 = 3.14E2; // 314.0
double deVar3 = 3.14E-2; // 0.0314
char 字元型
16 bit 位,可以是中文字元,使用單引號括起來,本質上是一個固定占用 2 位元組的無符號正整數,對應一個 Unicode 編號,用於表示 Unicode 編號對應的字元,預設值為空字元'\u0000'
。
由於固定占用兩個位元組,char
只能表示 Unicode 編號在 65536 以內的字元,而不能表示超出範圍的字元,超出範圍的字元將使用兩個 char 表示。
char crVar1 = '光';
char crVar2 = 97; // 可以存儲數字,因為 char 的本質就是無符號正整數,對應 Unicode 編號
boolean 布爾型
布爾型只有兩個取值:true
和 false
,預設值為 false
。
boolean flag = true;
基本數據類型轉換
在 Java 中,聲明變數時需要指定數據類型,JVM 會根據數據類型申請相應的記憶體空間,分配的空間只能存儲該類型的數據。如果賦值的數據類型和聲明的數據類型不一致,則需要進行數據類型轉換。
布爾型不參與數據類型轉換。
自動類型轉換
小取值範圍類型往大範圍類型轉自動轉。
byte => short => int => long => float => double
char => int
long 的位數比 float 大,但由於 float 採用科學計數法,取值範圍實際比 long 大。
byte a = 10;
short b = a;
int c = b;
long d = c;
強制類型轉換
大範圍往小範圍轉要強轉。強轉可能導致數據溢出、精度丟失。
float ftVar = (float)3.14159; // 浮點數字面量預設是 double 類型
隱式類型轉換
/*
1、多類型混合運算時,會自動轉成容量最大的數據類型,再進行計算,並返回相應類型的結果
對於整數來說,如果沒有 long 型,則提升至 int 型(不管有沒有 int 型變數參與)
2、在取值範圍內時,整數字面量(int 型)賦值給 byte、short、char 時會自動轉換
3、在取值範圍內時,常量和字面量的運算結果賦值給 byte、short、char 時會自動轉換
4、賦值運算(+=、-=、...)會自動進行強轉
5、`char` 的運算是按 Unicode 編號進行的,在進行算術運算時會轉換為 `int` 類型
*/
byte a = 100;
// a + 1 運算提升至 int 型,值在 byte 的取值範圍內,但由於是變數和字面量運算,編譯時不會優化,需要手動強轉
byte b = a + 1;
final byte c = 100;
// c + 1 運算提升至 int 型,值在 byte 的取值範圍內,且是常量和字面量運算,編譯時會優化,不需要手動強轉
byte d = c + 1;
// 100 + 1 運算提升至 int 型,值在 byte 的取值範圍內,且是字面量和字面量運算,編譯時會優化,不需要手動強轉
byte f = 100 + 1;
引用(對象)數據類型
除基本數據類型以外的,都是引用(對象)數據類型,如:String、數組...,引用類型的預設值是 null
。
引用數據類型由基本數據類型、其他引用數據類型組成,可以理解為自定義數據類型。