Двоични числа в Java

1. Въведение

Двоичната бройна система използва 0s и 1s за представяне на числа. Компютрите използват двоични числа за съхраняване и извършване на операции с всякакви данни.

В този урок ще научим как да преобразуваме двоично в десетично и обратно. Също така ще извършим събиране и изваждане върху тях.

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 в неговия двоичен формат, трябва:

  1. Разделете n на 2, като отбележите коефициента q и остатъка r
  2. Разделете q на 2, като отбележите неговото коефициент и остатък
  3. Повторете стъпка 2, докато получим 0 като фактор
  4. Обединете в обратен ред всички остатъци

Нека видим пример за преобразуване на 6 в еквивалент в двоичен формат:

  1. Първо разделете 6 на 2: коефициент 3, остатък 0
  2. След това разделете 3 на 2: коефициент 1, остатък 1
  3. И накрая, разделете 1 на 2: коефициент 0, остатък 1
  4. 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 приема два параметъра като вход:

  1. Двоичен низ, който трябва да се преобразува
  2. Радикс или основа на числовата система, в която входният низ трябва да бъде преобразуван

Сега, нека се опитаме да напишем нашата собствена логика за преобразуване на двоично число в десетично:

  1. Започнете от най-дясната цифра
  2. Умножете всяка цифра с 2 ^ {позиция} от тази цифра - тук позицията на най-дясната цифра е нула и тя се увеличава, когато се придвижваме вляво
  3. Добавете резултата от всички умножения, за да получите последното десетично число

Отново нека видим нашия метод в действие:

  1. Първо, 101011 = (1 * 2 ^ 5) + (0 * 2 ^ 4) + (1 * 2 ^ 3) + (0 * 2 ^ 2) + (1 * 2 ^ 1) + (1 * 2 ^ 0 )
  2. След това 101011 = (1 * 32) + (0 * 16) + (1 * 8) + (0 * 4) + (1 * 2) + (1 * 1)
  3. Тогава 101011 = 32 + 0 + 8 + 0 + 2 + 1
  4. И накрая, 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. Изваждане

Има много начини за изваждане на двоични числа. В този раздел ще научим нечий метод за допълване, за да направим изваждане.

Нека първо разберем какво е нечие допълнение към число.

One's complement of a number is a number obtained by negating each digit of the binary number. That means just replace 1 by 0 and 0 by 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()); }

To do subtraction of two binary numbers using one's complement, we need to:

  1. Calculate the one's complement of the subtrahend s
  2. Add s and the minuend
  3. If a carry gets generated in step 2, then add that carry to step 2's result to get the final answer.
  4. If a carry is not generated in step 2, then the one's complement of step 2's result is the final answer. But in this case, the answer is negative

Let's implement the above steps:

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)); } }

5. Conclusion

В тази статия научихме как да преобразуваме двоични числа в десетични и обратно. След това извършихме аритметични операции като събиране и изваждане на двоични числа.

Пълният код, използван в тази статия, е достъпен в GitHub.