Forum: Mikrocontroller und Digitale Elektronik Lange Variablen?


von Maruu (Gast)


Lesenswert?

Hallo,

ich hoffe es passt hierher.
Ich hab ein Steuergerät worauf sich ein 16Bit Prozessor befindet.
Dieser kann aber auch 32Bit Variablen adressieren, ich hab also in C
sowohl 16 als auch 32bit Variablen zur verfügung. Nun brauche ich aber
für eine große Zahl eine Variable die mindestens 46bit hat.
Jetzt ist die Frage ob es eine lib gibt oder ein Stück code wo genau
sowas gemacht wird, also zwei Variablen zusammenbasteln so das es nach
außen hin wie eine Variable mit 48Bit oder 64Bit auftritt und evt.
Grundrechenarten +,-,*,/ als Funktionen für diese zusammengesetzte
Variable implementiert sind?
Gibts sowas?

Gruß

Maruu

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

Evtl. ist das aber etwas zu mächtig: http://www.swox.com/gmp/

Matthias

von Maruu (Gast)


Lesenswert?

Hi!

Das kenn ich schon, leider is das etwas zu übertrieben, ich hatet evt
an etwas kleineres gedacht. Ich denke im uC bereich müsste solche
Probleme doch auchs chon aufgetreten sein, z.B. wenn man 8Bit Prozessor
hat und 16 Bit verarbeiten will. Ich würd auch was selber schreiben,
aber hab leider kein Plan wie die Rechenoperationen bei aufgeteilten
Zahlen funktionieren?

gruß

Maruu

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

du solltest doch in der Grundschule gewesen sein oder? ;-) (nicht böse
sein)

Dann sollten dir die Algorithmen für das Rechnen mit langen Zahlen bei
begrenzter Stellenzahl pro Operation geläufig sein. Bei uns in der
Grundschule nannte man das schriftliches Addieren, Subtrahieren,
Multiplizieren und Dividieren.

Die GMP liegt ja auch im Quellcode vor. Evtl. lohnt es sich auch mal
einen Blick da rein zu werfen.

Matthias

von Maruu (Gast)


Lesenswert?

Hi!

Jap ich war in der Grundschule. Das addieren der 2 zahlen müsste ich
noch hinbekommen, aber wie funktioniert das mit dem Multiplizieren?

Das kommt dann drauf an ob ich es in der Bit-Ebene betrachte oder ob
ich ganze Zahlen ablege in 2 int Variablen.
Wenn ich z.B. die Zahl 1234567890 hab und in einer Variable
12345 und in der anderen 67890 ablege und die komplette Zahl mit 456
Multiplizieren will.
Wie mach ich das dann?

Gruß

Maruu

von Rolf Magnus (Gast)


Lesenswert?

> Jap ich war in der Grundschule. Das addieren der 2 zahlen müsste
> ich noch hinbekommen, aber wie funktioniert das mit dem
> Multiplizieren?

12 * 34

ist da gleiche wie

(2 * 4) + (10 * 4) + (2 * 30) + (10 * 30)

Jetzt mußt du dir nur noch jede Ziffer durch ein Byte ersetzt denken.
Das Prinzip bleibt das gleiche. Übrigens: Wenn du zwei n-Bit-Zahlen
multiplizierst, brauchst du für das Ergebnis 2n Bits.

von Maruu (Gast)


Lesenswert?

Ahhh danke für die Info über multiplizieren, wusste ich so nicht.
Jap das ich 2n bits benötige weiß ich.
Bei mir wird auch nur das Ergebnis meienr rechnungen so lang deswegen
brauch ich die 46Bit.
Wie geht das ganze beim dividieren?

MFG

Maruu

von Unbkannter (Gast)


Lesenswert?

#include <stdint.h>

  int64_t   a;
  uint64_t  b;

  int32_t   c;
  uint32_t  d;

  int16_t   e;
  uint16_t  f;

  int8_t    g;
  uint8_t   h;

von T. Stütz (Gast)


Lesenswert?

wie wärs damit :

Multiplikation = wiederholte Addition
Division       = wiederholte Subtraktion

Bsp:

123 / 35

123 - 35 = 88
 88 - 35 = 53
 53 - 35 = 18
 Rest = 18, ich habe insgesammt 3mal die 35 abgezogen

=> Ergebnsi ist 3 mit Rest 18
   oder 3*35 + 18 = 123

Braucht aber sehr viel Zeit !!

Gruss

von Maruu (Gast)


Lesenswert?

Hallo

leider kann damit mein compiler nicht umgehen, und vor allem kann der
Prozessor keine 64Bit ints verarbeiten.

Gruß

Maruu

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Die Datenwortlänge des Prozessors spielt keine Rolle. Kennt dein
Compiler "long long int"?

von Maruu (Gast)


Lesenswert?

leider nein, das längste was er kennt ist long und das is bei ihm 32
bit, mehr ist leider nicht drin!

Gruß

Maruu

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Dann würde ich eine Struct aus einem long und einem int bauen und ein
paar Funktionen add(), sub(), mult() usw. dafür schreiben. Ist nicht
schön, aber eine andere Möglichkeit gibt es m.E. nicht. Eine fertige
Bibliothek wie gmp ist wahrscheinlich Overkill.

von Peter Dannegger (Gast)


Lesenswert?

Standardmäßig haben alle C-Compiler 8, 16 und 32 Bit integer und 32 Bit
floating point.

Und das hat auch nicht das geringste damit zu tun, ob die
Datenbusbreite 4, 8, 16, 32 oder 64 Bit ist.


Wenn Du zwar einen großen Dynamikbereich brauchst, aber nicht mehr als
24 Bit Genauigkeit, dann mach doch die Rechnungen einfach in floating
point.


Peter

von Rolf Magnus (Gast)


Lesenswert?

> Dann würde ich eine Struct aus einem long und einem int bauen und
> ein paar Funktionen add(), sub(), mult() usw. dafür schreiben. Ist
> nicht schön, aber eine andere Möglichkeit gibt es m.E. nicht.

In C++ könnte man die Operatoren überladen und so dafür sorgen, daß man
den Typ fast vollständig so benutzen kann wie von den anderen
Integertypen gewohnt. Die Arbeit beim Implementieren ist natürlich die
gleiche, aber die Benutzung sieht schöner aus.

> Standardmäßig haben alle C-Compiler 8, 16 und 32 Bit integer und
> 32 Bit floating point.

Das stimmt nicht. Sie müssen aber eigentlich einen Integer-Typ
anbieten, der mindestens 64bit breit ist.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

64 Bit muss es erst ab C99 geben, glaube ich.

von Rolf Magnus (Gast)


Lesenswert?

Ja. Frühere Versionen der Norm sind mit Erscheinen von C99 hinfällig
geworden und können seitdem auch nicht mehr bei ISO oder ANSI bezogen
werden.
Es ist ja auch nicht so, daß C99 erst gestern aus heiterem Himmel da
war. Das gibt es schon seit gut 6 Jahren, und schon lange vorher gab es
Drafts, die einige der neuen Features beschrieben hatten.
Klar, daß ein Compiler, der von 1999 veröffentlicht wurde, noch kein
C99 umsetzen muß, aber alles, was danach kam, darf sich eigentlich nur
ISO- oder ANSI-konform schimpfen, wenn es C99 umsetzt. Ist eigentlich
schon peinlich, wenn ein Compilerhersteller, der möglicherweise noch
kräftig Geld für den Compiler verlangt, es nach so vielen Jahren immer
noch nicht gebacken kriegt.

von Maruu (Gast)


Lesenswert?

Hi

Danke erstmal für die Antworten.

Also es handelt sich bei dem Steuergerät um ein relativ kleines das
meines wissens nach auch keine Fließkommaeinheit hat, deshalb könnenw
ir nicht mit float und schon garnicht mit großen floats rechnen.
Anstelle von fließkomma benutzen wir Fixkommaarithemtik und das geht
auch ganz gut. da schränkt sich zwar der Wertebereich eines int´s ein
aber man hat dafür auch nachkomamstellen ohne großen Aufwand.

da ich aber nun einen int brauch der min. 46 Bit hat werd ich wohl
einen Struct machen und die 4 Grundrechenarten implementieren.
*,+,- bekomm ich jetzt hin denke ich aber wie geht / (dividieren)?
Ich denke der Compiler is älter als 1999, never tpuch a running system
vor allem nicht wenn große Stückzahlen dahinter stecken!

Gruß

Maruu

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Das Gerät braucht keine Fließkommaeinheit, die Umsetzung Fließkomma ->
Integerrechnung macht der Compiler.

von Maruu (Gast)


Lesenswert?

OK das mag sein das das der kompiler macht, das löst aber das Problem
nicht!

Gruß

Maruu

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Wieso nicht?

von Maruu (Gast)


Lesenswert?

Weil mein kompiler kein float oder ähnliches hat/kann.
Und Fließkomma bringt mir insofern nix da ich nicht die genauigkeit bei
der Nachkommastelle sonder die vorkommawerte brauch. und dazu brauch ich
nen großen int.

Gruß

Maruu

von Unbkannter (Gast)


Lesenswert?

Jetzt mal konkret: Was ist denn das für ein komischer Compiler der im
Jahre 2005 weder ISO-C99-kompatibel ist noch den float-Datentyp für das
Zielsystem beherscht? Und was für ein Zielsystem ist das überhaupt?

Klingt reichlich exotisch...

von Maruu (Gast)


Lesenswert?

Hallo!

Jo genau kann ich es leider auch nicht sagen da ich es erstens nicht
weiß und zweitens denke ich mal nicht sagen darf. Die dinger werden
nachher im Auto verbaut und verarbeiten von verschiedenen Sensoren die
daten, berechnen werte und steuern displays oder andere Aktoren an. Da
es sich noch um recht alte Prozessoren handelt, is der Kompiler auch
nicht sehr neu denke ich und vor allem der Speicher ist recht knapp.

Ich muss jetzt eine Matrixinversion machen wo Werte bis 2 ^ 9 raus
kommen können die ich aber mit ner Auflösung von mind 0.001 ablegen
muss.
Und mit Fixkommaaritmethik geht das schon, aber dazu brauch ich größere
Integerwerte.
Also am kompiler werd ich (Praktikant) da sowieso nix drehen können
deswegen muss ich mir da was anderes überlegen.

Gruß

Maruu

von Läubi (Gast)


Lesenswert?

hm... kanst du nicht Dinge wie Carryfalg betrachten?

sagen wir du hast 2  4bit Zahlen brauhcst aber ne 8 bit "breite"

Dann machst du

R1 = obere 4 bit
R2 = untere 4 bit

R2 = R2 + 4bit des zu addierenden Wert
R1 = R1 + Carrybit + (evenutell oberen Teil der Zahl)


AUf die Weise hab ich z.B. bei nem 8bit Prozessor einen 24bit Wert
erzeugt und darauf dasn +, -, *, / implemnetiert (Multiplikation udn
Division sind über ABziehen/addieren gelöst)

von Unbkannter (Gast)


Lesenswert?

@Maruu:

Für mich klingt das eher so, als ob Du ein Problem lösen sollst damit
Dein Mentor sieht, ob Du überhaupt zu gebrauchen bist...

Du sollst Matrix-Berechnungen machen, hast aber keine Ahnung wie man
multipliziert und Dein Programm soll in ein Auto eingebaut werden?

Das klingt für mich, gelinde gesagt, unglaubwürdig.

von Peter Dannegger (Gast)


Lesenswert?

> Und Fließkomma bringt mir insofern nix da ich nicht die genauigkeit
> bei der Nachkommastelle sonder die vorkommawerte brauch.

Das ist Quatsch.
Die Mantisse ist 24 Bit und es ist egal, wo Du das Komma hinsetzt, Du
hast insgesamt 6 Dezimalstellen.


> Ich muss jetzt eine Matrixinversion machen wo Werte bis 2 ^ 9 raus
> kommen können die ich aber mit ner Auflösung von mind 0.001 ablegen
> muss.

Und wo ist das Problem ?

0,001 sind nochmal 10 Bit, du brauchst also insgesamt 9 + 10 = 19 Bit.

Wie sollen da 32 Bit nicht reichen ?


Peter

von Maruu (Gast)


Lesenswert?

@ Läubi:
Ja sowas in die Richtung muss ich bauen, nur ne Division mit abziehen
zu realisieren is denke ich ned die eleganteste Methode vor allem bei
sehr großen Zahlen.

@Unbkannter:
Mein programm läuft irgendwann in nem Steuergerät nur wird mein Code
nicht der endgültige sein, es geht im ersten Schritt nur mal drum zu
testen ob des alles funktioniert.
Und ja ich kann multiplizieren, nur weiß ich nicht wie man das verteilt
auf mehrere Variablen macht, hab ich in der Grundschule nicht gelernt!

@Peter Dannegger:
Sorry es tut mir leid, ich hab mich verschrieben, nciht 2 ^ 9 sondern
10 ^ 9, dasieht die Welt schon ganz anders aus.

Gruß

Maruu

von Rolf Magnus (Gast)


Lesenswert?

> @ Läubi:
> Ja sowas in die Richtung muss ich bauen, nur ne Division mit
> abziehen zu realisieren is denke ich ned die eleganteste Methode
> vor allem bei sehr großen Zahlen.

Dann erinnern wir uns wieder an die Grundschule und machen die Division
wie damals. Vielleicht hilft das dabei:

415 : 3 = 138 Rest 1
3                     -> 4 / 3 = 1 Rest 1  ( 3 * 1 = 3)
-
11
 9                    -> 11 / 3 = 3 Rest 2 ( 3 * 3 = 9)
--
 25
 24                   -> 25 / 3 = 8 Rest 1 ( 3 * 8 = 24)
 --
  1

von Peter Dannegger (Gast)


Lesenswert?

Nun gut, dann sinds 12 Dezimalstellen.


Ich bezweifle aber stark, wo Du so hochgenaue Eingangsgrößen
herbekommst und ob Du wirklich so eine supergenaue Ausgabe brauchst.


Im realen Leben reichen meistens 2..4 Dezimalstellen aus, der Rest ist
Rauschen.


Peter

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.