jak pisemnie dodawać binarne?

0

Niestety nie bardzo rozumiem zadanie, które powinienem wykonać (może dlatego, że javy uczę się od października).
Chodzi o to, że dla mnie najprościej byłoby dodać dwie liczby binarne zamieniając je na dziesiętne i potem sumę znowu zamieniając na binarną.
Ale w zadaniu chyba chodzi o coś innego, tzn. żeby tak na piechotę dodawać kolejne cyfry liczb binarnych do siebie.

package BinDecimal;

import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Scanner;

public class BinDecimal {
    private static final int base = 2;
    private static final String pattern = "01";

    public static String convertTo(int n) {
        String result = "";

        //n is equal to 0, do not process, return "0"
        if (n == 0)
            return "0";

        //process until n > 0
        while (n > 0) {
            result = pattern.charAt(n % base) + result;
            n /= base;
        }
        return result;
    }

    public static int convertFrom(String n) {
        int decimal = 0;
        return Integer.parseInt(n, 2);
    }

    public static void main(String[] args) {
        int choice;
        Scanner input = new Scanner(System.in);
        do {
            try {
                System.out.println("What do you want to do?");
                System.out.println("1. Convert binary to decimal");
                System.out.println("2. Convert decimal to binary");
                System.out.println("3. Sum of two binary");
                System.out.println("4. Multiplication of two binary");

                choice = input.nextInt();
                break;
            } catch (InputMismatchException ex) {
                System.out.println("Wrong format! Try again!");
                input.next();
            }
        } while (true);

        if (choice == 1) {
            System.out.println("Enter binary number: ");
            int n = input.nextInt();
            String number = String.valueOf(n);
            System.out.println(number + " w systemie dwojkowym to " + convertFrom(number) + " w systemie dziesietnym");

        } else if (choice == 2) {
            System.out.println("Enter decimal number: ");
            int number = input.nextInt();
            System.out.println(number + " w systemie dwojkowym = " + convertTo(number));
        } else if (choice == 3) {
            ArrayList<Character> list1 = new ArrayList<>();
            System.out.println("Enter binary number: ");
            int a = input.nextInt();
            String number1 = String.valueOf(a);
            for (int i = 0; i < number1.length(); i++) {
                list1.add(number1.charAt(i));
            }
            for (Character element : list1) {
                System.out.print(element + ", ");
            }

            System.out.println("Enter binary number: ");
            ArrayList<Character> list2 = new ArrayList<>();
            int b = input.nextInt();
            String number2 = String.valueOf(b);
            for (int i = 0; i < number2.length(); i++) {
                list2.add(number2.charAt(i));
            }
            for (Character element : list2) {
                System.out.print(element + ", ");


                int carry = 0;
                Character[] result = new Character[50];
                for (int i = 0; i <= list1.size(); i++) {
                    if (list1.get(i) + list2.get(i) + carry == 0) {
                        result[i] = 0;
                        carry = 0;
                    }

                    if (list1.get(i) + list2.get(i) + carry == 1) {
                        result[i] = 0;
                        carry = 0;
                    }

                    if (list1.get(i) + list2.get(i) + carry == 2) {
                        result[i] = 0;
                        carry = 1;
                    }

                    if (list1.get(i) + list2.get(i) + carry > 2) {
                        result[i] = 1;
                        carry = 1;
                    }
                }
            }


            System.out.println(number1 + " + " + number2 + "=" + ());

        } else if (choice == 4) {

        } else
            System.out.println("Bad choice!");
    }
}

No to tu nie mam jeszcze doświadczenia, bo lista z cyfr jednej i drugiej liczby może być różnej długości, a lista z sumy jeszcze innej.
Czy ktoś z Państwa miałby jakiś pomysł na to, żebym z zadaniem dobrnął do celu?
Jeśli by się to udało, to może potem dałbym już radę z mnożeniem...
Oto, co zrobiłem do tej pory:

Z góry bardzo dziękuję za każdą chęć pomocy.

0
  1. Podaj treść zadania.
  2. Do czytania liczb binarnych użyj input.nextInt(2);
  3. Przedłuż listy list1 i list2 (do rozmiaru max(list1.size(), list2.size()) + 1 dopisując zera z przodu.
0
bogdans napisał(a):
  1. Podaj treść zadania.
  2. Do czytania liczb binarnych użyj input.nextInt(2);
  3. Przedłuż listy list1 i list2 (do rozmiaru max(list1.size(), list2.size()) + 1 dopisując zera z przodu.

Napisz program który przyjmuje dwa napisy reprezentujące dwie liczby całkowite zapisane binarnie i wyświetli ich sumę zapisaną binarnie. Program powinien obliczać sumę "pisemnie".

0

Do rad, które padły powyżej, dodam: przemyśl powoli czy w tej instrukcji:
for (int i = 0; i <= list1.size(); i++)
warunek wykonania kolejnego obrotu pętli jest na pewno poprawny. Przemyśl powoli i zapamiętaj na zawsze ;-)

0

W zadaniu nie ma żadnego ograniczenia na dodawane liczby. Rozumiem że użytkownik może wpisać 111111111111111111111111111100000000000000000000000000001111111111111111111111111111110000000001
lub -11110001010101010? Wtedy trzeba inaczej czytać i inaczej dodawać. "Pisemne" dodawania ma wtedy sens, nie jest tylko męczeniem studentów.

0
bogdans napisał(a):

W zadaniu nie ma żadnego ograniczenia na dodawane liczby. Rozumiem że użytkownik może wpisać 111111111111111111111111111100000000000000000000000000001111111111111111111111111111110000000001
lub -11110001010101010? Wtedy trzeba inaczej czytać i inaczej dodawać. "Pisemne" dodawania ma wtedy sens, nie jest tylko męczeniem studentów.

Tak myślę, że o to chodzi, by była możliwość wpisania dowolnej liczby

1

Spróbuj tak (kod obsługuje tylko liczby dodatnie):

...
        else if (choice == 3) 
        {
            System.out.println("Enter binary number: ");
<= 1111111111110000000000000000011100000000000001100000000000000111
            BinaryNumber number1 = new BinaryNumber(input.next());
 
            System.out.println("Enter binary number: ");
<= 10101010101010101010101
            BinaryNumber number2 = new BinaryNumber(input.next());
            int length = Math.max(number1.digits.size(), number2.digits.size());
            number1.pad(length);
            number2.pad(length);
            
            BinaryNumber sum = number1.add(number2);
            System.out.println(number1 + " + " + number2 + " = " + sum);
=> 1111111111110000000000000000011100000000000001100000000000000111 + 10101010101010101010101 = 1111111111110000000000000000011100000000010110110101010101011100
        } 

Kod klasy BinaryNumber:

    class BinaryNumber
    {
        int sign = 1;
        ArrayList<Integer> digits = new ArrayList<>();
        //--------------------
        
        public BinaryNumber(String number)
        {
        	if(number.startsWith("-"))
        	{
        		sign = -1;
            	number = number.substring(1);
        	}
        	char[] chars = number.toCharArray();
        	for(int i = chars.length - 1; i >= 0; --i)
        	{
        		digits.add(chars[i] - '0');
        	}
        }
        //--------------------
        public BinaryNumber() 
        {}
		//--------------------
        private void pad(int length)
        {
        	while(digits.size() < length)
        	{
        		digits.add(0);
        	}
        }
        //--------------------
        private BinaryNumber add(BinaryNumber number)
        {
            BinaryNumber result = new BinaryNumber();
            int carry = 0;
            for(int i = 0; i < digits.size(); i++)
            {
            	result.digits.add(digits.get(i) ^ number.digits.get(i) ^ carry);
            	carry = (digits.get(i) + number.digits.get(i) + carry) >= 2 ? 1 : 0;
            }
            if(carry > 0)
            {
            	result.digits.add(carry);
            }
            
            return result;
        }
        //--------------------
        public String toString()
        {
        	StringBuffer sb = new StringBuffer();
        	if(sign < 0)
        	{
        		sb.append("-");
        	}
        	boolean onlyZeros = true;
        	int i = digits.size() - 1;
        	while(i >= 0)
        	{
        		if(!onlyZeros)
        		{
        			sb.append(digits.get(i));
        		}
        		else
        		{
        			if(digits.get(i) == 1)
        			{
        				sb.append("1");
        				onlyZeros = false;
        			}
        		}
        		--i;
        	}
        	if(sb.length() == 0)
        	{
        		sb.append("0");
        	}
        	return sb.toString();
        }
    }

...

1

Wygodniej z tych napisów zrobić Integery i dodać je w takiej funkcji:

import java.util.*;

class Addition{
	
	public static List<Integer> addition(List<Integer> a, List<Integer> b){
		List<Integer> out = new ArrayList<Integer>();
		for (int i = 0; i < a.size() + 1; i++)
			out.add(0);
		Collections.reverse(a);
		Collections.reverse(b);
		int carry = 0;
		int i = 0;
		for (i = 0; i < a.size(); i++){
		out.set(i, (a.get(i) + b.get(i) + carry) % 2);
		carry = (a.get(i) + b.get(i) + carry) / 2;
		}
		if (carry > 0)
			out.set(i, carry);
		Collections.reverse(out);
		return out;
	}

Jak widać, funkcja oczekuje liczb o równej długości (przed wysłaniem mniejszą trzeba uzupełnić zerami na początku), oraz, tuż przed zwróceniem wyniku, Usuń poczatkowe zera z listy out.

EDIT Żeby w ten sposób "obsłużyć" liczby ujemne, najwygodniej byłoby zaimplementować wcześniej odejmowanie - dodanie liczby ujemnej będzie odjęciem dodatniej.

0

@bogdans: He, he w tym samym czasie dodaliśmy praktycznie taki sam kod:) Działa Ci to poprawnie? Bo nie widzę, Żebyś gdzieś odwracał liczby przychodzące do add.

0

Jak Panowie to robią? Ja pół dnia męczę się ze swoim poprzednim średnim pomysłem i ciągle jeszcze mi nie wychodziło, a tu takie rozwiązanie. Państwa pomoc jest nieoceniona! Mój problem jest taki, że wciąż jeszcze muszę się uczyć sposobu wykorzystania podstawowych narzędzi, jak zresztą Państwo zauważają. Znacząco brakuje mi doświadczenia i cieszę się, że chcą się Państwo dzielić swoim. Dzięki Państwa pomocy, aż się chce tego dalej uczyć! Dziękuję!

PS. Zrobiłem sobie już też mnożenie, a tak siedziałbym jeszcze pewnie nad tym dłuuuugo.

0

Obsłużyłem dodawanie liczb ujemnych, dodałem też usuwanie zbędnych zer (metoda reduce) i wyliczanie wartość bezwzględnej (metoda abs). Metoda toString jest długa, nie zmieniła się więc ją pomijam.

import java.math.BigInteger;
import java.util.ArrayList;

public class BinaryNumber
{
	private int sign = 1;
	private ArrayList<Integer> digits = new ArrayList<>();
	private static BigInteger two = new BigInteger("2");
	private static BigInteger zero = BigInteger.ZERO;
	private static BigInteger one = BigInteger.ONE;
	//--------------------

	public BinaryNumber(String number)
	{
		if(number.startsWith("-"))
		{
			sign = -1;
			number = number.substring(1);
		}
		char[] chars = number.toCharArray();
		for(int i = chars.length - 1; i >= 0; --i)
		{
			digits.add(chars[i] - '0');
		}
	}
	//--------------------
	public BinaryNumber() 
	{}
	//--------------------
	private void pad(int length)
	{
		while(digits.size() < length)
		{
			digits.add(0);
		}
	}
	//--------------------
	private void reduce()
	{
		int index = digits.size() - 1;
		while(index >= 0 && digits.get(index) == 0)
		{
			digits.remove(index);
			--index;
		}
	}
	//--------------------
	public BigInteger abs()
	{
		BigInteger result = zero;
		BigInteger weight = one;
		BigInteger factor;
		for(int digit: digits)
		{
			factor = (digit == 0) ? zero : one; 
			result = result.add(weight.multiply(factor));
			weight = weight.multiply(two);
		}

		return result;
	}
	//--------------------
	public static BinaryNumber sum(BinaryNumber number1, BinaryNumber number2)
	{
		int length = Math.max(number1.digits.size(), number2.digits.size());
		number1.pad(length);
		number2.pad(length);        	
		BinaryNumber result = new BinaryNumber();
		int carry = 0;
		if(number1.sign*number2.sign > 0)
		{
			for(int i = 0; i < number1.digits.size(); ++i)
			{
				result.digits.add(number1.digits.get(i) ^ number2.digits.get(i) ^ carry);
				carry = (number1.digits.get(i) + number2.digits.get(i) + carry) >= 2 ? 1 : 0;
			}
			if(carry > 0)
			{
				result.digits.add(carry);
			}
		}
		else
		{
			int difference = 0;
			if(number2.abs().compareTo(number1.abs()) > 0)
			{
				BinaryNumber temp = number1;
				number1 = number2;
				number2 = temp;
			}
			for(int i = 0; i < number1.digits.size(); ++i)
			{
				difference = number1.digits.get(i) + carry - number2.digits.get(i);
				if(difference >= 0)
				{
					result.digits.add(difference);
					carry = 0;
				}
				else
				{
					result.digits.add(1);
					carry = -1;
				}
                                result.reduce();
			}
		}
		
		result.sign = number1.sign;
		number1.reduce();
		number2.reduce();
		return result;
	}
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1