Java中的二进制数字
Contents
1. 简介
二进制数字系统使用 0 和 1 来表示数字。计算机使用二进制数来存储和对任何数据执行操作。
在本教程中,我们将学习如何将二进制转换为十进制,反之亦然。此外,我们将对它们执行加法和减法。
2. 二进制字
Java 7 引入了二进制文字。它简化了二进制数的使用。
要使用它,我们需要在数字前加上 0B 或 0b:
@Test
public void given_binaryLiteral_thenReturnDecimalValue() {
byte five = 0b101;
assertEquals((byte) 5, five);
short three = 0b11;
assertEquals((short) 3, three);
int nine = 0B1001;
assertEquals(9, nine);
long twentyNine = 0B11101;
assertEquals(29, twentyNine);
int minusThirtySeven = -0B100101;
assertEquals(-37, minusThirtySeven);
}
3. 二进制数转换
在本节中,我们将学习如何将二进制数转换为十进制格式,反之亦然。在这里,我们将首先使用内置的 Java 函数进行转换,然后我们将为此编写自定义方法。
3.1. 十进制到二进制数
Integer有一个名为toBinaryString的函数,用于将十进制数转换为其二进制字符串:
@Test
public void given_decimalNumber_then_convertToBinaryNumber() {
assertEquals("1000", Integer.toBinaryString(8));
assertEquals("10100", Integer.toBinaryString(20));
}
现在,我们可以尝试为这种转换编写自己的逻辑。在写代码之前,我们先来了解一下如何将十进制数转换为二进制数。
要将十进制数 n转换为其二进制格式,我们需要:
- 将n除以 2,注意商q和余数r
- 将q除以2,注意它的商和余数
- 重复步骤 2,直到我们得到 0 作为商
- 以相反的顺序连接所有余数
让我们看一个将 6 转换为等效二进制格式的示例:
- 首先,将 6 除以 2:商 3,余数 0
- 然后,将 3 除以 2:商 1,余数 1
- 最后,将 1 除以 2:商 0,余数 1
- 110
现在让我们实现上面的算法:
public Integer convertDecimalToBinary(Integer decimalNumber) {
if (decimalNumber == 0) {
return decimalNumber;
}
StringBuilder binaryNumber = new StringBuilder();
Integer quotient = decimalNumber;
while (quotient > 0) {
int remainder = quotient % 2;
binaryNumber.append(remainder);
quotient /= 2;
}
binaryNumber = binaryNumber.reverse();
return Integer.valueOf(binaryNumber.toString());
}
3.2. 二进制转十进制数
为了解析二进制字符串,Integer类提供了一个 parseInt函数:
@Test
public void given_binaryNumber_then_ConvertToDecimalNumber() {
assertEquals(8, Integer.parseInt("1000", 2));
assertEquals(20, Integer.parseInt("10100", 2));
}
在这里,parseInt函数接受两个参数作为输入:
- 要转换的二进制字符串
- 必须在其中转换输入字符串的数字系统的基数或基数
现在,让我们尝试编写自己的逻辑来将二进制数转换为十进制数:
- 从最右边的数字开始
- 将每个数字乘以该数字的 2^{position} - 这里,最右边数字的位置为零,并且随着我们向左侧移动它增加
- 将所有乘法的结果相加得到最终的十进制数
再一次,让我们看看我们的方法:
- 首先,101011 = (1*2^5) + (0*2^4) + (1*2^3) + (0*2^2) + (1*2^1) + (1*2^0 )
- 接下来,101011 = (1*32) + (0*16) + (1*8) + (0*4) + (1*2) + (1*1)
- 那么,101011 = 32 + 0 + 8 + 0 + 2 + 1
- 最后,101011 = 43
让我们最后对上述步骤进行编码:
public Integer convertBinaryToDecimal(Integer binaryNumber) {
Integer decimalNumber = 0;
Integer base = 1;
while (binaryNumber > 0) {
int lastDigit = binaryNumber % 10;
binaryNumber = binaryNumber / 10;
decimalNumber += lastDigit * base;
base = base * 2;
}
return decimalNumber;
}
4. 算术运算
在本节中,我们将专注于对二进制数执行算术运算。
4.1. 添加
就像十进制数加法一样,我们从最右边的数字开始添加数字。 在添加两个二进制数字时,我们需要记住以下规则:
- 0 + 0 = 0
- 0 + 1 = 1
- 1 + 1 = 10
- 1 + 1 + 1 = 11
这些规则可以实现为:
public Integer addBinaryNumber(Integer firstNum, Integer secondNum) {
StringBuilder output = new StringBuilder();
int carry = 0;
int temp;
while (firstNum != 0 || secondNum != 0) {
temp = (firstNum % 10 + secondNum % 10 + carry) % 2;
output.append(temp);
carry = (firstNum % 10 + secondNum % 10 + carry) / 2;
firstNum = firstNum / 10;
secondNum = secondNum / 10;
}
if (carry != 0) {
output.append(carry);
}
return Integer.valueOf(output.reverse().toString());
}
4.2. 减法
有很多方法可以减去二进制数。在本节中,我们将学习一个补码方法来做减法。
让我们首先了解什么是数字的补码。
一个数的补码是通过对二进制数的每个数字求反而获得的数。这意味着只需将 1 替换为 0 并将 0 替换为 1:
public Integer getOnesComplement(Integer num) {
StringBuilder onesComplement = new StringBuilder();
while (num > 0) {
int lastDigit = num % 10;
if (lastDigit == 0) {
onesComplement.append(1);
} else {
onesComplement.append(0);
}
num = num / 10;
}
return Integer.valueOf(onesComplement.reverse().toString());
}
要使用补码对两个二进制数进行减法运算,我们需要:
- 计算减数 s的补码
- 加 s和被减数
- 如果在步骤 2 中生成了进位,则将该进位添加到步骤 2 的结果中以获得最终答案。
- 如果第 2 步没有产生进位,则第 2 步结果的反码即为最终答案。但在这种情况下,答案是否定的
让我们实现上述步骤:
public Integer substractBinaryNumber(Integer firstNum, Integer secondNum) {
int onesComplement = Integer.valueOf(getOnesComplement(secondNum));
StringBuilder output = new StringBuilder();
int carry = 0;
int temp;
while (firstNum != 0 || onesComplement != 0) {
temp = (firstNum % 10 + onesComplement % 10 + carry) % 2;
output.append(temp);
carry = (firstNum % 10 + onesComplement % 10 + carry) / 2;
firstNum = firstNum / 10;
onesComplement = onesComplement / 10;
}
String additionOfFirstNumAndOnesComplement = output.reverse().toString();
if (carry == 1) {
return addBinaryNumber(Integer.valueOf(additionOfFirstNumAndOnesComplement), carry);
} else {
return getOnesComplement(Integer.valueOf(additionOfFirstNumAndOnesComplement));
}
}