Forum: Mikrocontroller und Digitale Elektronik Bruchrechnung mit großen ganzen Zahlen


von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

wie scheibt man in AVR-gcc richtig die Rechnung

wordvariable3 = 6000000 / ( wordvariable1 × (1+ wordvariable2))

auf.

Es würde auch ein Link zu einer entsprechenden Erklärung genügen.
Es geht mir hier um den Umgang mit großen Zahlen, der mir aktuell nicht 
mehr geläufig ist.

Schon mal danke und mit freundlichem Gruß

von Jim M. (turboj)


Lesenswert?

Aus Deiner Berschreiubng geht nicht hervor ob mit oder ohne Vorzeichen.
Daher besser fertiges Beispiel als Anhang hochladen.

Aber ich versuche mal:
1
wordvariable3 = 6000000 / ( wordvariable1 * (1UL+ wordvariable2))

Das 1UL macht die 1 zu einem "unsigned long".

Besorge Dir mal ein C Buch. Da kann man sowas nachlesen.

von H.Joachim S. (crazyhorse)


Lesenswert?

Verstehe die Frage nicht so ganz.
Steht "Bruchrechnung" jetzt dafür, dass du dividieren willst oder soll 
das Ergebnis tatsächlich ein Bruch sein? Oder willst du was optimieren?
Für Ganzzahlrechnung stimmt es doch schon fast wie es da steht, ein "*" 
für die Multiplikation und ein ";" ans Zeilenende.
Soll das Ergebnis ein Bruch sein, ist float dein Freund.

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

danke schon mal. Das Ergebnis soll eine ganze Zahl sein und kein Bruch.

Die Variablen sind vorzeichenlos, also immer positiv. Es ging mir darum, 
wo ich UL schreiben muß oder ob da noch ein cast dazu muß.

Werde es demnächst mal testen.

Mit freundlichem Gruß

von Stefan F. (Gast)


Lesenswert?

C geht von int aus, sofern die offensichtlichen Zahlen und Variablen 
dort hinein passen.

Dein Literal 6000000 passt nicht in einen einfachen int, deswegen mach C 
daraus einen long int. Wenn es ein unsigned long int werden soll, musst 
das auch hinschreiben, in deinem Fall macht es jedoch keinen 
Unterschied. Die 6000000 sind also Ok.

Der Ausdruck (wordvariable1 * (1+ wordvariable2)) wird mit einem 
Algorithmus berechnet, der nur int Größe unterstützt, weil beide 
Variablen von diesem Typ sind und die 1 ebenfalls in einen int rein 
passt. Die Multiplikation führt bei großen Werten zu einem Überlauf, 
deswegen möchtest du den Compiler dazu bringen, diesen Ausdruck mit 
einem anderen Algorithmus zu berechnen, der long int unterstützt. Das 
erreichst du, indem du entweder eine der beiden Variablen als long int 
deklarierst, oder das Literal 1 in 1UL änderst.

Got it?

von Stefan F. (Gast)


Lesenswert?

Wenn du jedoch Anstelle der 1UL, den Typ einer Variable ändern würdest, 
gäbe es einen kleinen aber wichtigen Unterschied zu beachten:

(longvariable1 * (1+ intvariable2))

In diesem Fall würde der innere Teil-Ausdruck "1+intvariable2" als 
Integer berechnet. Wenn intvariable2 dabei schon den maximalen Wert 
eines Integers hat und du dann noch 1 addierst, bekommt du wegen 
Überlauf ein völlig falsches Ergebnis. Besser ist also:

(intvariable1 * (1+ longvariable2))

Denn nun wird der innere Teil-Ausdruch als long Integer berechnet und 
unterstützt somit wesentlich größere Zahlen. Der Außere Ausdruck wird 
zwangsläufig ebenfalls als logn integer berechnet da dessen rechter 
Operator (=das Ergebnis des inneren Teilausdruckes) ein long integer 
ist.

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

und wegen diesen Spezialitaten habe ich gefragt, wie man das richtig 
macht. Vielen Dank nochmals.

Mit freundlichem Gruß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.