jak pisemnie dodawać binarne?

jak pisemnie dodawać binarne?
GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
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.

Kopiuj
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.

edytowany 4x, ostatnio: bogdans
bogdans
Nie zgaduj jak wyglądają znaczniki kolorujące tylko wybierz z listy.
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
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.

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 2x, ostatnio: bogdans
GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
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".

SN
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:11
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 ;-)

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
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.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
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

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
1

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

Kopiuj
...
        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:

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

...

Kopiuj

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:4 minuty
  • Postów:4896
1

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

Kopiuj
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.


edytowany 2x, ostatnio: lion137
bogdans
A co wcześniej zaimplementować, żeby "obsłużyć" odejmowanie liczb ujemnych ? ;)
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:4 minuty
  • Postów:4896
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.


edytowany 2x, ostatnio: lion137
bogdans
Ja odwracam w konstruktorze, wtedy jest trochę prostsze uzupełnianie - bo na końcu.
lion137
Acha, już widzę:)
GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
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.

edytowany 1x, ostatnio: geoinfomat
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
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.

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

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)