Seite 1 von 1

Multiplikation

Verfasst: Donnerstag 11. April 2013, 12:40
von fail
Multiplikationsalgorithmus ohne * oder module zu benutzen.

Funktioniert für [-999999,.....,-2,-1,0,1,2,.......,999999]

Code: Alles auswählen

def multiplication(a,b):
	if b>=0:
		return sum(a for _ in range(b))
	elif a<0 and b<0:
		return sum(-a for _ in range(-b))
	else:
		return sum(b for _ in range(a))

Re: Multiplikation

Verfasst: Donnerstag 11. April 2013, 12:49
von EyDu
Du hast im Prinzip drei identische Zeilen, welche jeweils die Summe bilden. Daher solltest du diese aus den if/elif/else-Blöcken rausziehen und darin nur die Dinge behandeln, welche tatsächlich unterschiedlich sind.

Auch, wenn es sich hier nur um Spielerei handelt: probiere mal ``multiplication(1, 1000000000)`` und ``multiplication(1000000000, 1)`` aus und überlege dir, warum sich die Aufrufe unterschiedlich verhalten.
fail hat geschrieben:Funktioniert für [-999999,.....,-2,-1,0,1,2,.......,999999]
Was willst du damit sagen? Dass es für alle ganzen Zahlen funktioniert?

Re: Multiplikation

Verfasst: Donnerstag 11. April 2013, 13:12
von fail
Ja, es funktioniert nur für ganze zahlen.
Meinst du das die kleinere Zahl im range() sein sollte?

Re: Multiplikation

Verfasst: Freitag 12. April 2013, 09:59
von EyDu
fail hat geschrieben:Meinst du das die kleinere Zahl im range() sein sollte?
Ja, das wäre geschickter. Aber das Beispiel ist ja eh nur akademischer Natur.

Re: Multiplikation

Verfasst: Freitag 12. April 2013, 15:00
von BlackJack
@fail: Es gibt übrigens noch eine effizientere Methode die mit Bit-Verschiebungen und Addition auskommt. Also die Operatoren ``<<``, ``>>``, und ``+``.

Re: Multiplikation

Verfasst: Freitag 12. April 2013, 16:08
von fail
Ist das Cheating

Code: Alles auswählen

def multiplication(a,b):
	return a/(1/b)

Re: Multiplikation

Verfasst: Freitag 12. April 2013, 18:08
von EyDu
Nein, das ist eine nichtfunktionierende Lösung (b=0). Davon abgesehen handelst du dir natürlich die üblichen Probleme mit floats ein.

Re: Multiplikation

Verfasst: Samstag 13. April 2013, 11:51
von jerch
BlackJack hat geschrieben:@fail: Es gibt übrigens noch eine effizientere Methode die mit Bit-Verschiebungen und Addition auskommt. Also die Operatoren ``<<``, ``>>``, und ``+``.
Als Fingerübung kann man auch gleich die Addition mittels Bitoperatoren mit umsetzen. Interessant dürften da AND (&) und XOR (^) sein. :D

Re: Multiplikation

Verfasst: Sonntag 14. April 2013, 16:50
von fail
Ich schaff die addition einfach nicht. Ich hab schon alles versucht. Der Fehler ist wahrscheinlich in der Addition funktion, aber ich kann ihn nicht finden.

Code: Alles auswählen

from functools import reduce

def addition(a,b):
    a = list(map(int,list(bin(a)[2:])))
    b = list(map(int,list(bin(b)[2:])))
    remainder = 0
    resultat=[]
    for c in reversed(range(max(len(a),len(b)))):
        resultat.append(adder(get(a,c),get(b,c),remainder)[0])
        remainder=adder(get(a,c),get(b,c),remainder)[1]
    return bin2dec(list(reversed(resultat)))

def adder(a,b,cin):
    s=cin ^ a ^ b
    cout=(a&b)| (cin&(a^b))
    return s,cout

def get(von,das):
    try:
        return von[das]
    except IndexError:
        return 0

def bin2dec(binary):
        return reduce(lambda acc,y: acc*2 + y,binary)        
        

Re: Multiplikation

Verfasst: Sonntag 14. April 2013, 17:20
von BlackJack
@fail: Ich würde es ja nicht mit einzelnen Bits in einer Liste machen sondern mit den Zahlen und den Bitoperationen selbst, denn die werden intern ja schon binär gespeichert.

Edit:

Code: Alles auswählen

def add(a, b):
    while True:
        a, b = a ^ b, b & a
        if b == 0:
            return a
        b <<= 1

Re: Multiplikation

Verfasst: Sonntag 14. April 2013, 17:40
von jerch
@fail:
Das ist viel zu kompliziert gedacht. Schau Dir mal einen Halbaddierer an. Das kann man gut übertragen.

Edit:
Kleine Ergänzung, um den Überlauf für bestimmte Vorzeichensituationen loszuwerden:

Code: Alles auswählen

def add(a, b):
    if a == -b:
        return 0
    if a < b:
        a, b = b, a
    if a > 0 and b < 0:
        if -b < a:
            return -add(-a, -b)
    while True:
        a, b = a ^ b, b & a
        if b == 0:
            return a
        b <<= 1

Re: Multiplikation

Verfasst: Montag 15. April 2013, 11:53
von nomnom
@jerch: Du benutzt doch in deinem Code ständig "-", das ist doch unfair :p Dann geht auch

Code: Alles auswählen

add = lambda a, b: a - (-b)

Re: Multiplikation

Verfasst: Montag 15. April 2013, 21:07
von derdon
Die Klammern sind überflüssig:

Code: Alles auswählen

>>> a, b = 23, 42
>>> a--b
65

Re: Multiplikation

Verfasst: Montag 15. April 2013, 21:42
von nomnom
derdon hat geschrieben:Die Klammern sind überflüssig:

Code: Alles auswählen

>>> a, b = 23, 42
>>> a--b
65
Und woher soll Python dann wissen, ob nicht (a-)-b gemeint war????

Re: Multiplikation

Verfasst: Montag 15. April 2013, 21:54
von BlackJack
@nomnom: Öhm, das wäre ein `SyntaxError`:

Code: Alles auswählen

n [86]: (a-)-b
  File "<ipython-input-86-e4fa2a309856>", line 1
    (a-)-b
       ^
SyntaxError: invalid syntax

Re: Multiplikation

Verfasst: Montag 15. April 2013, 22:28
von jerch
nomnom hat geschrieben:@jerch: Du benutzt doch in deinem Code ständig "-", das ist doch unfair :p Dann geht auch

Code: Alles auswählen

add = lambda a, b: a - (-b)
Ok, Abkürzungen gelten nicht:

Code: Alles auswählen

ZERO = 0
ONE = 1

# simple 1 testing
def is_one(a):
    return ONE if a==ONE else ZERO

# xor equal testing
def equal(a, b):
    return is_one(((a^b) << ONE) | ONE)

# testing for zero (lazy version with using equal)
def is_zero(a):
    return equal(a, ZERO)

# simple incrementor
def inc(a):
    if equal(a, ~ZERO):
        return ZERO
    b = ONE
    while ONE:
        if is_zero(b):
            return a
        a, b = a^b, (a&b) << ONE

# negativate number: positive to negative and negative to positive
def neg(a):
    if is_zero(a):
        return a
    return inc(~a)
Jetzt kannst Du das '-' mit neg() ersetzen. Damit kannst Du die komplette Intergerarithmetik auf Bitoperatoren und den basalen 1 oder 0 Test zurückführen. Hochintegrierte ALUs waren gestern, hoch leben die Register ;)
(Zur Anschaulichkeit hab ich 1 und 0 mal durch "Konstanten" ersetzt)