
在处理二进制数据时,我们常常需要自定义数据结构来封装特定的二进制位数。这里以一个表示8位二进制数的 octet 类为例。octet 类内部使用一个 int 数组来存储8位二进制值(0或1)。
public class Octet {
int[] x = new int[8]; // 存储8位二进制数,x[0]为最高位,x[7]为最低位
// 构造函数:接受一个8位二进制字符串
Octet(String s){
if (s.length() != 8) {
System.out.println("Too few or too many characters"); // 简单的错误提示
// 实际应用中可能抛出IllegalArgumentException
return;
}
for (int i = 0; i < 8; i++) {
// 将字符串的第i位(从左到右)映射到数组的相应位
// s.charAt(i) 是从左到右,x[7 - i] 意味着s的第0位是x[7],s的第7位是x[0]
// 这与通常的二进制表示(高位在前)相反,需要注意
// 修正:如果希望s的第0位是x[0](最高位),s的第7位是x[7](最低位),则应是 x[i] = ...
// 根据原始代码,x[7-i]意味着字符串的第一个字符(最高位)存储在x[7],最后一个字符(最低位)存储在x[0]。
// 然而,octetToString()方法是从x[0]到x[7]逆序构建字符串,这将导致x[0]成为字符串的第一个字符(最高位)。
// 为了保持一致性,假设x[0]是最高位,x[7]是最低位。
// 那么构造函数应该修改为:x[i] = (s.charAt(i) == '1' ? 1 : 0);
// 这里我们遵循原始代码的意图,但需要理解其内部表示与字符串表示的转换逻辑。
// 原始代码的逻辑:
// s = "10000000" (表示128)
// x[7] = 1, x[6]=0, ..., x[0]=0
// octetToString() 会将 x[0] 放在结果字符串的开头,即 "00000001"
// 这实际上是反向的二进制表示。
// 为了与标准的 Integer.parseInt(..., 2) 兼容,我们需要确保 octetToString() 返回的是标准的高位在前的二进制字符串。
// 修正后的构造函数(使x[0]为最高位,x[7]为最低位):
x[i] = (s.charAt(i) == '1' ? 1 : 0);
}
}
// 将 Octet 转换为字符串形式(高位在前)
String octetToString() {
String result = "";
for (int i = 0; i < 8; i++) {
// 从x[0](最高位)开始构建字符串
result += x[i];
}
return result;
}
// 待实现的加法方法
Octet sum(Octet y){
// ...
return null; // 占位符
}
}重要提示: 原始代码中 Octet 构造函数和 octetToString 方法的位序处理存在不一致或反向的问题。为了与 Integer.parseInt(String, int) 和 Integer.toBinaryString(int) 的标准高位在前(Most Significant Bit first)的二进制字符串表示保持一致,我们对上述 Octet 类的代码进行了修正。修正后,x[0] 代表最高位,x[7] 代表最低位,octetToString() 方法会生成一个标准的高位在前的二进制字符串。
现在,我们的目标是实现 sum(Octet y) 方法,它将当前 Octet 对象与另一个 Octet 对象 y 相加,并返回一个新的 Octet 对象作为结果。由于直接对二进制数组进行位操作比较复杂,一个更简便且常用的方法是利用Java内置的整数转换功能:
public class Octet {
int[] x = new int[8]; // x[0]为最高位,x[7]为最低位
// 构造函数:接受一个8位二进制字符串,并按标准高位在前填充数组
Octet(String s){
if (s.length() != 8) {
throw new IllegalArgumentException("Octet string must be exactly 8 characters long.");
}
for (int i = 0; i < 8; i++) {
char bitChar = s.charAt(i);
if (bitChar == '1') {
x[i] = 1;
} else if (bitChar == '0') {
x[i] = 0;
} else {
throw new IllegalArgumentException("Octet string must contain only '0' or '1'.");
}
}
}
// 将 Octet 转换为字符串形式(高位在前)
String octetToString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < 8; i++) {
result.append(x[i]);
}
return result.toString();
}
// 实现两个 Octet 对象的加法
Octet sum(Octet y){
// 1. 将当前 Octet 对象和参数 Octet 对象转换为十进制整数
// Integer.parseInt(String s, int radix) 可以将指定基数的字符串转换为整数
int o1Decimal = Integer.parseInt(this.octetToString(), 2); // 当前对象的十进制值
int o2Decimal = Integer.parseInt(y.octetToString(), 2); // 参数对象的十进制值
// 2. 执行十进制加法
int sumDecimal = o1Decimal + o2Decimal;
// 3. 将十进制和转换回二进制字符串
String binarySum = Integer.toBinaryString(sumDecimal);
// 4. 处理二进制字符串的长度
// 检查结果是否超过8位(溢出)
if(binarySum.length() > 8){
// 两个 Octet 的和超出了8位二进制数的表示范围
// 在实际应用中,可以抛出自定义异常、返回特殊值或截断处理
throw new ArithmeticException("Sum of octets exceeds 8 bits: " + binarySum);
}
// 结果二进制字符串可能不足8位,需要在前面补零
StringBuilder resultBuilder = new StringBuilder(binarySum);
while(resultBuilder.length() < 8) {
resultBuilder.insert(0, "0"); // 在开头插入零
}
// 5. 使用处理后的二进制字符串创建并返回新的 Octet 对象
return new Octet(resultBuilder.toString());
}
// 示例:添加一个equals和hashCode方法用于对象比较,以及一个main方法进行测试
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Octet octet = (Octet) o;
return java.util.Arrays.equals(x, octet.x);
}
@Override
public int hashCode() {
return java.util.Arrays.hashCode(x);
}
public static void main(String[] args) {
try {
Octet octet1 = new Octet("00000001"); // 1
Octet octet2 = new Octet("00000010"); // 2
Octet sum1_2 = octet1.sum(octet2);
System.out.println("00000001 + 00000010 = " + sum1_2.octetToString()); // 期望: 00000011 (3)
Octet octet3 = new Octet("11111111"); // 255
Octet octet4 = new Octet("00000001"); // 1
try {
Octet sum3_4 = octet3.sum(octet4); // 期望: 溢出
System.out.println("11111111 + 00000001 = " + sum3_4.octetToString());
} catch (ArithmeticException e) {
System.out.println("Overflow expected: " + e.getMessage());
}
Octet octet5 = new Octet("00001010"); // 10
Octet octet6 = new Octet("00000101"); // 5
Octet sum5_6 = octet5.sum(octet6);
System.out.println("00001010 + 00000101 = " + sum5_6.octetToString()); // 期望: 00001111 (15)
// 测试无效输入
try {
new Octet("101");
} catch (IllegalArgumentException e) {
System.out.println("Invalid input expected: " + e.getMessage());
}
try {
new Octet("1010101x");
} catch (IllegalArgumentException e) {
System.out.println("Invalid input expected: " + e.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}通过将自定义的 Octet 对象转换为Java内置的十进制整数进行计算,然后将结果再转换回二进制字符串并重新封装成 Octet 对象,我们可以相对简便地实现自定义二进制类的加法操作。关键在于确保二进制字符串与十进制整数之间的转换逻辑正确无误,并妥善处理可能出现的溢出情况。这种方法不仅清晰易懂,而且利用了Java标准库的强大功能,是实现此类操作的有效途径。
以上就是Java中Octet类加法操作的实现与二进制处理的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号