BCD 到十進制轉換
1. 簡介
在本教程中,我們將研究數字的二進位編碼的十進位 (BCD) 格式,並介紹幾種將 BCD 轉換為十進位格式的方法。
2. BCD格式
2.1. 定義
BCD 是一種數位系統,我們用四位元二進位或半位元組表示每個十進位數字 [0 – 9]。例如,十進位數 14 的 BCD 表示形式是 1110。在需要直接使用十進位表示(例如數字顯示、財務計算和計時)的系統中,我們會使用 BCD,因為這些系統允許更直接地在十進制和二進制之間進行轉換。
2.2. 映射
下表顯示了十進位到 BCD 的映射:
| 十進制數字 | BCD 咬合 |
|---|---|
| 0 | 0000 |
| 1 | 0001 |
| 2 | 0010 |
| 3 | 0011 |
| 4 | 0100 |
| 5 | 0101 |
| 6 | 0110 |
| 7 | 0111 |
| 8 | 1000 |
| 9 | 1001 |
2.3. 類別
根據儲存(包裝)方式,我們將BCD分為以下兩類:
- 打包
- 解壓縮
對於壓縮版本,我們將兩個 BCD 半位元組儲存在一個位元組中。此外,我們主要使用一個 8 位元暫存器進行儲存。因此,這是一種高效的儲存方式,因為我們利用了 100% 的空間。
對於非打包類型,每個 BCD 半位元組都儲存在其各自的暫存器中。因此,對於 8 位元暫存器來說,我們浪費了空間,因此這種類型並非最佳選擇。
3. BCD 和純二進位
BCD 碼不同於純二進位格式。在二進位格式中,我們將數字作為一個整體處理,得到一個二進位值。在 BCD 碼中,我們將數字中的每一位都表示為 BCD 半位元組。例如,15 的二進位形式是 1111,而它的 BCD 碼是 0001 0101。
4. 透過位元運算將 BCD 轉換為十進位
這是將單一壓縮的 BCD 位元組(8 位元)轉換為其十進制等效值的最直觀的方法。
在這種方法中,我們對包含兩個 BCD 半位元組的位元組使用位元運算。
為此,我們使用高 4 位表示十位,低 4 位表示個位。首先,我們右移 ( >> ) 將高半位元組移到低位,然後執行按位AND ( & ) 操作,分離出相關的 4 位,並屏蔽掉其餘位:
public static int convertPackedByte(byte bcdByte) {
int upperNibble = (bcdByte >> 4) & 0x0F;
int lowerNibble = bcdByte & 0x0F;
if (upperNibble > 9 || lowerNibble > 9) {
throw new IllegalArgumentException(
String.format("Invalid BCD format: byte 0x%02X contains non-decimal digit.", bcdByte)
);
}
resultDecimal = upperNibble * 10 + lowerNibble;
return resultDecimal;
}
顯然,該方法對於單字節打包的 BCD 值非常有效。
現在,讓我們測試一下這個方法:
@Test
void testConvertPackedByteValidValues() {
// Test 05 (0x05) ->
assertEquals(5, BCDtoDecimalConverter.convertPackedByte((byte) 0x05));
// Test 22 (0x22) -> 22
assertEquals(22, BCDtoDecimalConverter.convertPackedByte((byte) 0x22));
// Test 97 (0x097) -> 97
assertEquals(97, BCDtoDecimalConverter.convertPackedByte((byte) 0x097));
}
5. 透過陣列將 BCD 轉換為十進位
對於較大的十進制數,我們使用陣列來儲存 BCD 值,因為陣列允許我們將半位元組儲存在多個位元組中。對於轉換,我們遍歷每個字節,按照上一節中的按位邏輯進行操作,然後迭代構建十進制結果:
public static long convertPackedByteArray(byte[] bcdArray) {
long resultDecimal = 0;
for (byte bcd : bcdArray) {
int upperNibble = (bcd >> 4) & 0x0F;
int lowerNibble = bcd & 0x0F;
if (upperNibble > 9 || lowerNibble > 9) {
throw new IllegalArgumentException("Invalid BCD format: nibble contains non-decimal digit.");
}
resultDecimal = resultDecimal * 100 + (upperNibble * 10 + lowerNibble);
}
return resultDecimal;
}
接下來,我們透過執行以下測試程式碼來查看convertPackedByte()實際作用:
@Test
void testConvertPackedByteArrayValidValues() {
// Test 0 -> [0x00]
assertEquals(0L, BCDtoDecimalConverter.convertPackedByteArray(new byte[]{(byte) 0x00}));
// Test 99 -> [0x99]
assertEquals(99L, BCDtoDecimalConverter.convertPackedByteArray(new byte[]{(byte) 0x99}));
// Test 1234 -> [0x12, 0x34]
byte[] bcd1234 = {(byte) 0x12, (byte) 0x34};
assertEquals(1234L, BCDtoDecimalConverter.convertPackedByteArray(bcd1234));
// Test 12345678 -> [0x12, 0x34, 0x56, 0x78]
byte[] bcdLarge = {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78};
assertEquals(12345678L, BCDtoDecimalConverter.convertPackedByteArray(bcdLarge));
}
6. 結論
在本文中,我們研究了 BCD 數字格式以及將其轉換為十進制數係統的幾種方法。
由於應用程式需求和使用者輸入的多樣性,我們經常需要進行數位格式轉換。在 Java 中,BCD 到十進位格式的轉換是一項常見任務,我們可以透過多種方式完成。我們可以使用位元運算或陣列處理。這兩種方法都透過提取和組合這些 4 位元半位元組來解碼 BCD 碼。
本文的程式碼可在 GitHub 上找到。