Java-數據類型與編碼(ASCII、Unicode 和 UTF-8)


機械硬盤硬件結構(了解)https://diy.pconline.com.cn/cpu/study_cpu/1009/2215404_all.html

 

一、數據儲存單位

1.bit(位)

https://www.bilibili.com/video/av55918101

計算機數據在硬盤中,以機械硬盤為例,其內部由磁性材料制成。磁極有 N\S 兩級,可表示兩種狀態。可以看成 0/1。這是計算機最小儲存單位,稱為

2.Byte(字節)

一塊磁盤中有許多這樣的小磁塊,可以表示許多 0/1。而 0/1 正好可以表示二進制數

單單看一個二進制數並沒有什么價值。上個世紀 60 年代,美國制定了一套字符編碼,對英語字符二進制數之間的關系,做了統一規定。這被稱為 ASCII 碼,一直沿用至今。

ASCII 碼一共規定了 128 個字符的編碼。如空格(SPACE)是 32(00100000),大寫字母 A 是 65(01000001)。這 128 個符號(包括 32 個不能打印出來的控制符號),只占用了一個字節的后面 7 位,最前面的一位統一規定為 0。

ASCII 碼中 1 Byte = 8 bit,后來也就默認一字節等於八位了。

 

二、編碼

1.字符

字符並不是一個儲存單位,而是一個語言符號。由此來引出碼表與編碼問題。

英語用 128 個符號使用 ASCII 碼表就夠了,但是用來表示其他語言,128 個符號是不夠的。

簡體中文常見的碼表是 GB2312,使用兩個 Byte 表示一個漢字,所以理論上最多可以表示 256 x 256 = 65536 個符號。

2.Unicode 碼表

世界上這么多國家,存在着多種碼表,同一個二進制數字可以被解釋成不同的符號。因此,要想打開一個文本文件,就必須知道它對應的碼表,否則用錯誤的碼表解讀,就會出現亂碼。

可以想象,如果有一種編碼,將世界上所有的符號都納入其中。每一個符號都給予一個獨一無二的編碼,那么亂碼問題就會消失。這就是 Unicode,是一種所有符號的碼表。

Unicode 現在的規模可以容納 100 多萬個符號。每個符號的編碼都不一樣。如,U+0041 表示英語的大寫字母 A,U+4E25 表示漢字嚴(具體的符號對應表,可以查詢 unicode.org,或者專門的 漢字對應表)。

以往一套碼表對應一種編碼方式。如 ASCII 中 8 bit 為一個字符,GB2312 中 16 bit 為一個字符。用了 Unicode 后就不行了,靠前的字符二進制數值小,靠后的字符二進制數值大。

若全部以最長字符的位數去編碼,那靠前的字符就會出現許多 0 填充,造成了許多空間浪費。所以用了 Unicode 碼表后,計算機要以多少位去編碼就是一個問題。

3.UTF-8 編碼(由 RFC 3629 定義)

首先 UTF-8Unicode 的實現方式之一。其它實現方式還有 UTF-16((UCS-2)字符用兩個字節或四個字節表示)和 UTF-32((UCS-4)字符用四個字節表示)

UTF-8 最大的一個特點,就是它是一種變長的編碼方式。它使用 1~4 個字節表示一個符號,根據不同的符號而變化字節長度。

UTF-8 的編碼規則很簡單,只有二條:

  • 對於單字節的符號,字節的第一位設為 0,后面 7 位為這個符號的 Unicode 碼。因此對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。
  • 對於 n(n > 1)字節的符號,第一個字節的前 n 位都設為 1,第 n + 1 位設為0,后面字節的前兩位一律設為 10。剩下的沒有提及的二進制位,全部為這個符號的 Unicode 碼。

下表總結了編碼規則,字母 x 表示可用編碼的位。

Unicode符號范圍      |       UTF-8編碼方式
(十六進制)           |           (二進制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

以漢字嚴為例

  • 嚴的 Unicode 是 4E25(100111000100101)
  • 根據上表,4E25 處在第三行的范圍內(0000 0800 - 0000 FFFF),因此嚴的 UTF-8 編碼需要三個字節,即格式是 1110xxxx 10xxxxxx 10xxxxxx。
  • 從嚴的最后一個二進制位開始,依次從后向前填入格式中的 x,多出的位補 0。這樣就得到了嚴的 UTF-8 編碼 11100100 10111000 10100101,轉換成十六進制就是 E4B8A5。

 

三、Java 基本數據類型

關於 boolean 型存儲

Java 虛擬機中會將 boolean 映射到 int,使用 1 來表示 true,0 表示 false。
即 boolean 型占用 1 bit。
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.3.4

關於浮點型范圍

https://blog.csdn.net/shichimiyasatone/article/details/85276316

關於自動拆裝箱

https://www.cnblogs.com/dolphin0520/p/3780005.html

關於類型轉換

  • 當在計算中有不同精度的數時,Java 會將低精度的操作數轉換成高精度的操作數,然后進行運算。運算的結果也是高精度的值。
  • 將一個高精度的值轉換成低精度值的時,要確定這個高精度類型變量的值是否能夠在低精度中表示。
  • 低精度到高精度為自動類型轉換((byte,short,char)--int--long--float--double)
  • 高精度到低精度為強制類型轉換

 


https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.2.1

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

http://www.ruanyifeng.com/blog/2014/12/unicode.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM