Höhere Mathematik

Gast #21404
Lesenswert?

wie kann ich mit dem avr eigentlich komplexere rechenoperationen 
durchführen? hab im befehlssatz nix gefunden was mir beim wurzel ziehen, 
potenieren, ja noch nicht mal beim multiplizieren oder dividieren helfen 
könnte. muss ich mir alles selbst programmieren? :O o.O
Gast #21411
Lesenswert?

dann lass es ihn doch in asm machen, das geht! Hab mich lange damit 
rumgeplagt (zu Zeiten, als es noch kein Internet gab, Z80...). Und ich 
bin wirklich froh, daß diese Kapitel hinter mir liegt.
Es ist ja nicht nur das Problem, einen effektiven Algorithmus für die 
diversen Funktionen zu finden und diesen zu programmieren, sondern die 
Fehlersuche treibt einen fast zur Verzweiflung, besonders die, die nur 
sporadisch auftreten.
Ich wüßte keinen Grund, diese Erfahrung andere auch selbst machen zu 
lassen...:-)
Gast #21412
Lesenswert?

Also, wie gesagt, ich würde in den Application Notes von Atmel schauen. 
Wenn du z.B. größere Zahlen multiplizieren willst, dann musst du das wie 
beim schriftlichen multiplizieren in zwei Teile aufteilen und addieren. 
Ist ein Riesenspass, wie meine Vorredner schon gesagt haben...
die division ist auch nicht soo schwer zu erweitern, wenn man das System 
dahinter verstanden hat...
Gast #21413
Lesenswert?

Floating Point ist auch kein Problem - wenn man weiß wie es geht (ich 
weiß es nicht... ;-)
Mal im Ernst: Es gibt den Basic-Interpreter des legendären 8052-BASIC 
inzwischen als Freeware. Man muß sich dann zwar mit einem anderen 
Assembler-Dialekt herumschlagen, aber die Floating-Point Routinen 
sollten sich auf den AVR adaptieren lassen.
#21414
Lesenswert?

Ich weiß jetz nicht, wo das Problem liegt.

Die Algorithmen sind doch bekannt, bzw. lassen sich in 
Mathematik-Grundlagenbüchern finden.

Der AVR macht es einem besonders einfach, da er 32 Register zum Rechnen 
hat.

Da die Algorithmen schon uralt sind, muß man sich damit auch nicht lange 
rumplagen. Einfach die Instruktionen entsprechen der gewünschten 
Bitanzahl kaskadieren.

Anbei als Beispiel eine Division 56 / 24 Bit.


Peter
Angehängte Dateien:
Gast #21416
Lesenswert?

Naja, Mul und Div krieg ich auch noch hin. Aber was ist mit Quadrat und 
Wurzel? Ich brauchte mal sowas zur Berechnung einer Standardabweichung, 
der nötige Zahlenbereich ist dann ziemlich schnell ziemlich groß 
geworden, da hab ich's sein lassen.

Ok, Quadrat wäre Multiplikation einer Zahl mit sich selbst. Wurzel wäre 
sukkzessive Annäherung. Aber es muß doch auch eleganter gehen?

Sven
Gast #21418
Lesenswert?

@Stefan: Hat Sven doch auch schon geschrieben...

@Sven:
"Eleganter" ist evtl. das Rechnen per Logarithmus. Auf alle Einzelheiten 
möchte ich nicht eingehen, das sprengt den Rahmen hier, aber man kann 
mit dieser Methode die Rechenoperationen vereinfachen:
Die Multiplikation läßt sich auf eine Addition zurückführen:
aus:

Ergebnis = Zahl1 * Zahl2

wird:

LN(Ergebnis) = LN(Zahl1) + LN(Zahl2)

Division wäre dann Subtraktion.

Oder Potenzieren:

LN(Ergebnis) = LN(Zahl) * LN(Potenz)

Die Quadratwurzel ist übrigens x^0,5. Mit dieser Methode kann man 
notfalls auch die 4. Wurzel ziehen: x^0,25.
Oder LN(Ergebnis) = LN(Zahl) / LN(Wurzel).

Der Nachteil bei dieser Sache: Man muß in einer Tabelle die Logarithmen 
ablegen und zwischenwerte durch interpolieren annähern. Allerdings läßt 
sich dann mit den Zahlen einiges anfangen....

Es ist übrigens egal, ob LN (der natürliche Logarithmus) oder LG 
(Logarithmus zur Basis 10) verwendet wird, man darf nur nicht mischen.
Gast #21420
Lesenswert?

Also Tabelle ist nicht so doll, die wird ziemlich schnell ziemlich groß, 
und man braucht Zeit zum Suchen.

Für x=Wurzel(n) habe ich einen Näherungsalgorithmus gefunden, der ist 
recht schnell, braucht allerdings eine Division. Berechnet in 10 
Durchläufen Wurzel aus 65000, und nutzt die Bytes sehr gut aus. Heißt 
bei 2 Byte kann ich Wurzel bis 65534 ziehen. Hat allerdings noch keine 
Bereichsabfrage (Null) und keine Rundungsfehler berücksichtigt, das 
müßte man noch einbauen.

Ich hab das mal in QBasic simuliert.

Sven

'Rekursion xneu=1/2(xalt+n/xalt)

INPUT n

x = 1             'Startwert
FOR i = 1 TO 20   'oder bis Wert konstant *)
  z = x
  x = n \ z
  x = x + z
  x = x \ 2
  PRINT x, x * x  'Ergebnis bzw. Zwischenwert
NEXT

*) Achtung, einige Werte scheinen bei Rechnung mit ganzen Zahlen zu 
alternieren, bei Wurzel 255 kann er sich nicht zwischen 15 und 17 
entscheiden. Im Zweifelsfall der kleinere Wert.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren