计算机基础系列文章
计算机基础(一):ASCll、GB2312、GBK、Unicode、UTF-32、UTF-16、UTF-8深度解析
一、进制基础概念
1、二进制(Binary)
- 基数为
2
,由0
和1
组成,是计算机底层数据存储的基本形式 - 以
0b
或0B
开头 - 示例:二进制
0b1010
表示十进制的10
2、八进制(Octal)
- 基数为
8
,由0-7
组成,作用是简化二进制表示
- 以
0
开头 - 示例:八进制
012
表示十进制的10
3、十进制(Decimal)
- 基数为
10
,由0-9
组成,是我们日常生活中使用的进制
4、十六进制(Hexadecimal)
- 基数为
16
,由0-9
和A-F
(或a-f
)组成,其中A
到F
表示10
到15
,常用于简化二进制表示
- 以
0x
或0X
开头 - 示例:十六进制
0xA
表示十进制的10
数制的基本要素:
二、进制转换原理
1、十进制 → R进制(短除法)
- 规则:不断
除以
目标进制基数
,倒序取余数
- 示例1:十进制
10
转二进制:10 ÷ 2 = 5 ··· 余 0 5 ÷ 2 = 2 ··· 余 1 2 ÷ 2 = 1 ··· 余 0 1 ÷ 2 = 0 ··· 余 1 结果:0b1010(逆序拼接余数)
- 示例2:十进制
50
转十六进制:50 ÷ 16 = 3 ··· 余 2 3 ÷ 16 = 0 ··· 余 3 结果:0x32(从下往上读)
2、R进制 → 十进制(位权展开)
- 规则:每位
数字
乘以基数的幂次
(从右向左,幂次从0开始) - 示例1:二进制
0b1010
转十进制:1×2³ + 0×2² + 1×2¹ + 0×2⁰ = 8 + 0 + 2 + 0 = 10
- 示例2:十六进制
0x2AF
转十进制:2×16² + 10×16¹ + 15×16⁰ = 512 + 160 + 15 = 687
3、二进制 ↔ 八进制/十六进制(分组转换)
- 二进制 → 八进制:每3位一组(不足补0),转换为1位八进制数
- 示例:
0b101010
→101
(5) +010
(2) →52
- 示例:
- 二进制 → 十六进制:每4位一组(不足补0),转换为1位十六进制数
- 示例:
0b101010
→0010(前面补了两个0)
(2) +1010
(A) →2A
- 示例:
- 反向转换:八/十六进制每位拆分为3/4位二进制
三、Java内置进制转换方法
1、十进制 → R进制
// 十进制转二进制
Integer.toBinaryString(13);
// 或者
Integer.toString(13,2); // "1101"
// 十进制转八进制
Integer.toOctalString(29);
// 或者
Integer.toString(13,8); // "35"
// 十进制转十六进制
Integer.toHexString(29);
// 或者
Integer.toString(13,16); // "1d"
2、R进制 → 十进制
- 通用方法:
Integer.parseInt(String str, int radix)
// 二进制 → 十进制
Integer.parseInt("1101", 2); // 13
// 八进制 → 十进制
Integer.parseInt("35", 8); // 29
// 十六进制 → 十进制
Integer.parseInt("1D", 16); // 29
3、进制间间接转换(通过十进制中转)
// 二进制转十六进制
String bin = "1101";
int anInt = Integer.parseInt(bin, 2); // 二进制 → 十进制
String hex = Integer.toString(anInt, 16); // 十进制 → 十六进制 -> "d"
// 十六进制转八进制
String hex1 = "A";
int decimal = Integer.parseInt(hex, 16); // 十六进制 → 十进制
String octal = Integer.toOctalString(decimal); // 十进制 → 八进制 → "12"
4、格式化输出
在 Java 中,使用System.out.printf
来格式化十进制
数为二进制
、八进制
或十六进制
,可以通过指定不同的格式化参数来实现。
public class Main {
public static void main(String[] args) {
int num = 255; // 示例十进制数
// 输出十进制数
System.out.printf("十进制: %d\n", num); // 十进制: 255
// 输出二进制数
System.out.printf("二进制: %s\n", Integer.toBinaryString(num)); // 二进制: 11111111
// 输出八进制数
System.out.printf("八进制: %o\n", num); // 八进制: 377
// 输出十六进制数(小写)
System.out.printf("十六进制 (小写): %x\n", num); // 十六进制 (小写): ff
// 输出十六进制数(大写)
System.out.printf("十六进制 (大写): %X\n", num); // 十六进制 (大写): FF
}
}
5、进制转换中的常见陷阱
数值溢出
:转换结果超出int范围(最大2147483647)
// 错误示例
Integer.parseInt("2147483648"); // NumberFormatException
// 正确做法
Long.parseLong("2147483648");
无效字符
:进制与字符不匹配
Integer.parseInt("12G3", 16); // G超出十六进制范围
- 八进制前缀混淆:以
0开头的十进制数
int num = 035; // 八进制29,非十进制35
四、自定义进制转换算法
- 当处理超大数(超出
Integer
范围)或需灵活控制时,可手动实现
1、十进制 → R进制(短除法实现)
public static String decimalToR(int num, int radix) {
if (num == 0) return "0";
StringBuilder sb = new StringBuilder();
while (num > 0) {
int remainder = num % radix;
// 处理十六进制字母
char c = (remainder < 10) ? (char)('0' + remainder) : (char)('A' + remainder - 10);
sb.append(c);
num /= radix;
}
return sb.reverse().toString(); // 倒序输出余数
}
// 示例:decimalToR(10, 16) → "A"
2、R进制 → 十进制(位权展开实现)
public static int rToDecimal(String str, int radix) {
int result = 0;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
int digit = Character.digit(c, radix); // 将字符转为对应数字
result = result * radix + digit;
}
return result;
}
// 示例:rToDecimal("1010", 2) → 10
五、进制转换实战应用
1、计算机内部存储与处理
计算机内部处理的数据通常采用二进制表示。但为了便于人类理解,数据常常以其他进制表示(如十六进制或十进制)。
示例:
内存地址
:计算机使用二进制表示地址,但人类更容易使用十六进制
表示
2、网络通信与协议
在网络通信中,IP地址和端口号常常使用十进制或十六进制表示。通过进制转换,可以有效地表示和处理网络数据。。
示例:
IPv4 地址
:通常以点分十进制格式(如192.168.1.1
)表示,但计算机内部使用二进制格式处理MAC 地址
:通常采用十六进制格式,表示网络硬件设备的唯一标识符
3、 颜色表示
在图形和图像处理中,像素的颜色值通常用十六进制表示。每种颜色通过红、绿、蓝三个分量表示,每个分量的值通常为 0 到 255(即 8 位二进制数)。
示例:
RGB颜色
表示:#FF5733(十六进制)
对应的 RGB 颜色为255, 87, 51(十进制)
4、加密算法与哈希算法
在加密领域,进制转换在密钥生成、加密、解密以及哈希值的表示中也有应用。哈希算法的结果常常以十六进制表示,以便人类读取。
示例:
SHA-256 哈希值
:将任意输入(如文件或字符串)转换为256位的哈希值,通常以十六进制
字符串表示,例如:7b8b965ad4bca0e41ab51de7b31363a1