Java Programming 【Chapter 2_QA】
1、大端序(Big Endian)、小端序(Little Endian)的概念理解、举例说明。

什么是大端序和小端序?
- 端序(Endianness)是指计算机系统中多字节数据(如整数)在内存中的存储顺序。
- 大端序(Big Endian):高位字节(数值较大的部分)存储在低地址,低位字节存储在高地址,像是“从左到右”读数,类似我们日常书写习惯。
- 小端序(Little Endian):低位字节存储在低地址,高位字节存储在高地址,像是“从右到左”读数,计算机更常使用这种方式优化计算。
通俗类比
想象一个三位数“123”要写在纸上:
- 大端序:像正常书写,先写“1”(高位)在左边,再写“2”“3”(低位)向右,像“123”。
- 小端序:像倒着写,先写“3”(低位)在左边,再写“2”“1”(高位)向右,像“321”,但实际读时要反过来理解。
举例说明
假设一个 16 位整数 0x1234(十六进制,十进制 4660),用 2 个字节表示:
- 内存地址:从 0x100 开始,占 2 字节(0x100 和 0x101)。
- 大端序:
- 0x100 存高位字节 0x12。
- 0x101 存低位字节 0x34。
- 内存:12 34,读出来是 0x1234。
- 小端序:
- 0x100 存低位字节 0x34。
- 0x101 存高位字节 0x12。
- 内存:34 12,读出来仍需解释为 0x1234。
为什么有区别?
- 硬件优化:小端序便于处理器直接处理低位数据(如加减法),常见于 Intel x86 架构。
- 网络传输:大端序常用于网络协议(如 TCP/IP),因为它更直观,类似人类阅读习惯。
- 兼容性:不同系统可能采用不同端序,需转换(如 UTF-16 Big/Little Endian)。
红框内容中的应用
- UTF-16 Big Endian:Unicode 字符用 2 字节存储,高位字节先存(如 0x9A6C 存为 9A 6C)。
- UTF-16 Little Endian:低位字节先存(如 0x9A6C 存为 6C 9A)。
- BOM(字节顺序标记):文件开头可能加特殊字节(如 FE FF 表示 Big Endian)帮助识别端序。
重点总结
- 大端序:高位在前,像“123”,适合人类阅读。
- 小端序:低位在前,像“321”但反读,优化计算。
- 区别:存储顺序相反,影响数据解释,需根据上下文(硬件或协议)选择。
2、在 Java 中,有哪些位移运算?例如 左移 <<, 右移 >> 有符号左移,无符号左移,有符号右移,无符号右移?
在 Java 中,位移运算符用于对整数的二进制表示进行位操作。以下是常见的位移运算符及其概念、区别,并通过举例说明。
位移运算符及概念
- 左移运算符 <<
- 概念:将操作数的二进制位向左移动指定位数,低位补 0,高位溢出被丢弃。
- 特性:相当于将数字乘以 2^n(n 为移位数),但可能溢出。
- 适用范围:对所有整数类型(int、long 等)。
- 有符号右移运算符 >>
- 概念:将操作数的二进制位向右移动指定位数,保留符号位(正数补 0,负数补 1),低位溢出被丢弃。
- 特性:相当于将数字除以 2^n 并向下取整,保持符号。
- 适用范围:对有符号整数(int、long)。
- 无符号右移运算符 >>>
- 概念:将操作数的二进制位向右移动指定位数,高位统一补 0,低位溢出被丢弃。
- 特性:将负数转为正数,相当于逻辑右移,忽略符号。
- 适用范围:对所有整数类型。
- 无符号左移
- 注意:Java 中没有专门的“无符号左移”运算符,<< 对所有整数都按相同方式操作(低位补 0),符号无关。
区别
- 符号处理:
- <<:不考虑符号,仅左移补 0。
- >>:考虑符号,补符号位(0 或 1)。
- >>>:不考虑符号,始终补 0。
- 溢出行为:
- <<:高位溢出可能改变符号。
- >> 和 >>>:低位溢出被丢弃。
- 用途:
- <<:乘法优化。
- >>:带符号的除法优化。
- >>>:无符号数处理或位操作。
举例说明
假设使用 int 类型,初始值 a = 12(二进制 00001100,32 位补齐高位 0)。
1. 左移 <<
int a = 12; int b = a << 2; // 左移 2 位 System.out.println(b); // 输出 48
- 过程:00001100 左移 2 位成 00110000(十进制 48)。
- 解释:相当于 12×22=12x2^2=48,低位补 0,高位溢出。
2. 有符号右移 >>
int a = 12; int b = a >> 2; // 右移 2 位 System.out.println(b); // 输出 3
- 过程:00001100 右移 2 位成 00000011(十进制 3)。
- 解释:相当于 12÷2^2=3,高位补 0(正数)。
3. 有符号右移(负数示例)
int a = -12; // 二进制补码 11111111 11111111 11111111 11110100 int b = a >> 2; // 右移 2 位 System.out.println(b); // 输出 -3
- 过程:11110100 右移 2 位成 11111101(补 1,因负数),十进制 -3。
- 解释:保持符号,相当于 −12÷4=−3。
4. 无符号右移 >>>
int a = -12; // 二进制补码 11111111 11111111 11111111 11110100 int b = a >>> 2; // 无符号右移 2 位 System.out.println(b); // 输出 1073741821
- 过程:11110100 右移 2 位成 00111101(高位补 0),补齐 32 位为 00111111 11111111 11111111 11111101,十进制 1073741821。
- 解释:忽略符号,转换为正数。
5. 无符号左移(使用 <<)
int a = 12; int b = a << 2; // 左移 2 位 System.out.println(b); // 输出 48 int c = -12 << 2; // 负数左移 System.out.println(c); // 输出 -48
- 过程:-12 的补码左移 2 位,高位溢出,保持负数。
- 解释:<< 对正负数行为一致,仅补 0。
总结表
| 运算符 | 补位规则 | 符号影响 | 典型用途 |
|---|---|---|---|
| << | 低位补 0 | 无 | 乘以 2^n |
| >> | 补符号位 (0/1) | 有 | 除以 2^n (带符号) |
| >>> | 高位补 0 | 无 | 无符号右移 |
注意
- 移位次数超过类型位数(32 位 int)会取模(例如 << 34 相当于 << 2)。
- 负数补码需理解二进制表示,>>> 常用于位掩码或无符号转换。
3、如何理解上述左移<<的如下计算结果?
int c = -12 << 2; // 负数左移 System.out.println(c); // 输出 -48
1. 理解负数 -12 的二进制表示
- Java 使用 补码(Two's Complement)表示有符号整数。
- int 类型是 32 位,-12 的二进制表示需要从正数 12 开始计算:
- 正数 12 的二进制:00001100(低 8 位,32 位高位补 0)。
- 补码计算:
- 取反:11110011(对每位取反)。
- 加 1:11110100(加上 1)。
- 因此,-12 的 32 位补码是:11111111 11111111 11111111 11110100。
- 符号位:最高位 1 表示负数。
2. 左移运算 << 2
- 左移规则:<< 将二进制位向左移动指定位数(这里是 2 位),低位补 0,高位溢出被丢弃。
- 对 -12 的补码 11111111 11111111 11111111 11110100 左移 2 位:
- 原数:11111111 11111111 11111111 11110100
- 左移 2 位:11111111 11111111 11111111 11010000(低位补 2 个 0,高位 2 位溢出)。
- 结果:新的 32 位二进制数 11111111 11111111 11111111 11010000。
3. 转换为十进制
- 这一串二进制是补码形式,需转换为十进制:
- 符号位 1 表示负数,取反加 1 还原。
- 取反:00000000 00000000 00000000 00101111。
- 加 1:00000000 00000000 00000000 00110000 = 48(十进制)。
- 负数值:-48。
- 验证:-12 << 2 相当于 −12×4=−48,与计算一致。
4. 为什么是 -48?
- 左移效果:<< 2 相当于乘以 2^2 =4。对于正数 12 << 2 = 48,负数 -12 << 2 保持符号,变为 -48。
- 补码特性:左移不改变符号位(最高位仍为 1),只是扩展了数值幅度,负数变“更负”。
简图说明
初始 (-12): 1111 1111 1111 1111 1111 1111 1111 0100 左移 2 位: 1111 1111 1111 1111 1111 1111 1101 0000 结果 (-48): 保持符号位 1,低位补 0。
总结
- -12 << 2 的结果是 -48,因为:
- -12 的补码左移 2 位,得到 11111111 11111111 11111111 11010000。
- 补码转换为十进制,符号位 1 表示负数,值是 -48。
- 数学上,-12 x 4 = -48,与位运算结果一致。
- 关键点:左移保持符号,负数左移加倍负值幅度。

浙公网安备 33010602011771号