Forum: PC-Programmierung long long int auf 32bit cpu


von Mike B. (sunmils)


Lesenswert?

moinmoin,

habe heute mal aus jux mit

sizeof(long long); // --> gibt 8 zurück

den wert einer long long Variablen abgefragt. Hätte eigentlich mit dem 
Ergebnis 4 gerechnet, da ich einen 32-bit Prozessor habe. Jetz frag ich 
mich was bringt mir eine 64bit variable auf einem 32bit Rechner. Wenn 
ich mich richtig erinnere sollte doch long long nur auf 64-bit CPUs 
64bit groß sein.

Kann mich mal jemand aufklären? Google hilft leider auch nicht wirklich 
weiter.

von Franko P. (sgssn)


Lesenswert?

Hallo

Was nutzt der Datentyp "float" auf einem uC der nur eine Intergereinheit 
hat? long long ist einfach nur ein Datentyp, der von einer 
Mathebibliothek gemanagt wird. Was machst du, wenn dir 32Bit, zb. als 
Zähler nicht reicht ?

Gruß
Gerhard

von D. I. (Gast)


Lesenswert?

long long ist nun mal der 64bit Datentyp in C. long long hat mit der 
Architektur anders wie int weniger zu tun.
Was bringts? einen höheren Wertebereich

von Mike B. (sunmils)


Lesenswert?

d.h. also wenn ich zwei Variablen multipliziere, und das Ergebnis in 
einer long long speichere kann es größer als 32-bit sein? Das kann dann 
aber nur gehen, weil der Akkumulator 64bit hat, oder?

Gerhard G. schrieb:
> long long ist einfach nur ein Datentyp, der von einer
> Mathebibliothek gemanagt wird.

Also eine Mathebibliothek kann man da wohl ausschliessen, was du meinst 
sind wohl bignums die sicher nicht im C-Standard sind, sondern extra 
Bibliotheken brauchen.

Gerhard G. schrieb:
> Was machst du, wenn dir 32Bit, zb. als
> Zähler nicht reicht ?

dann muss ich eine zweite Variable verwenden oder eben bignums. anders 
geht es nicht

von Mark .. (mork)


Lesenswert?

>d.h. also wenn ich zwei Variablen multipliziere, und das Ergebnis in
>einer long long speichere kann es größer als 32-bit sein? Das kann dann
>aber nur gehen, weil der Akkumulator 64bit hat, oder?

Nein, das geht auch bei einem 8-Bitter. Die Multiplikation (und andere 
Operationen) wird dann in mehreren Einzelschritten ausgeführt.

>Gerhard G. schrieb:
>> Was machst du, wenn dir 32Bit, zb. als
>> Zähler nicht reicht ?

>dann muss ich eine zweite Variable verwenden oder eben bignums. anders
>geht es nicht

Doch, in dem Du eben einen long long nimmst. Der hat überall mind. 64 
Bit.

MfG Mark

von Mike B. (sunmils)


Lesenswert?

sorry, muss nochmal genau nachfragen, denn unser prof hat uns da glaub 
ich was anderes erzählt. Du meinst also, das z.B. ein 32bit Rechner von 
der Architektur so gebaut ist, das er Berechnungen mit Operanden größer 
als 32bit auf mehrere Berechnungen aufteilt und später dann in einer 
Variable zusammenfügt. Also max. 64bit bei long long??

Also bspw. 4294967296 +1

werd ich gleich mal probiern...

von Tobi (Gast)


Lesenswert?

Du glaubst doch nicht wirklich das man auf einem C64 mit seinem 8-Bit 
Prozessor nur bis 256 hätte rechnen können, oder ? Ein Prozessor zerlegt 
größere Berechnungen nicht in viele kleine Schritte, sondern das muss 
schon dein Programm machen.

von Mike B. (sunmils)


Lesenswert?

ok, habs getestet mit:

long long int a,b=4294967296;
a=b+1;
printf("4294967296 + 1 = %lld",a);

und es funzt tatsächlich. War mir neu. Wenn du mir noch sagen kannst wie 
mein 32bit Celeron das macht wäre dir ich echt dankbar.

von Mark .. (mork)


Lesenswert?

>sorry, muss nochmal genau nachfragen, denn unser prof hat uns da glaub
>ich was anderes erzählt. Du meinst also, das z.B. ein 32bit Rechner von
>der Architektur so gebaut ist, das er Berechnungen mit Operanden größer
>als 32bit auf mehrere Berechnungen aufteilt und später dann in einer
>Variable zusammenfügt. Also max. 64bit bei long long??

Ja genau. Jede CPU hat das sog. Carry-Flag (Übertragsflag). Es gibt bei 
Rechenoperationen an, ob ein Überlauf stattgefunden hat. Wenn z.B. zu 
4294967295 eine 1 dazuaddiert wird, dann ist das Ergebnis 0 und Carry 
gesetzt. Wenn die Zielvariable ein 64-Bit wert sein soll, wird zu einer 
0 eine 0 und das Carry addiert, so dass das Ergebnis der zweiten 
Operation in diesem Fall eine 1 ist. Das sind dann die höherwertigen 
32-Bits der 64-Bit Variable, während das Ergebnis der ersten Operation 
die niederwertigen 32 Bit sind. Das ganze zusammen ergibt dann die 
64-Bit Variable. Wenn die zu addierenden Werte selbst auch 64 Bit sind, 
werden eben zuerst die niederwertigen 32 Bits addiert und dann die 
höherwertigen + Carry. Auf diese Weise kann man beliebig breite Zahlen 
addieren / subtrahieren. Bei einer Multiplikation 64Bit mit 64Bit müssen 
auf einer 32-Bit Maschine 4 Operationen durchgeführt werden.

Wenn Du per Hand rechnest, kannst Du ja auch nur 1-Stellige Werte 
aufeinmal handhaben. Trotzdem kannst Du beliebig große Zahlen in 
mehreren Schritten bearbeiten.

Siehe auch http://de.wikipedia.org/wiki/%C3%9Cbertragsbit

MfG Mark

von Markus K. (markus-)


Lesenswert?

Mike B. schrieb:
> Du meinst also, das z.B. ein 32bit Rechner von
> der Architektur so gebaut ist, das er Berechnungen mit Operanden größer
> als 32bit auf mehrere Berechnungen aufteilt und später dann in einer
> Variable zusammenfügt. Also max. 64bit bei long long??

Das hat er nicht gesagt.
Dieses aufteilen und zusammenfügen macht der Compiler, nicht die CPU.

Man kann da auch noch einen Schritt weiter gehen. Es gibt ja auch CPUs, 
die gar nicht multiplizieren können. Trotzdem kann man da in C 
mulitplizieren.

Markus

von Helmut L. (helmi1)


Lesenswert?

Mike B. schrieb:
> Wenn du mir noch sagen kannst wie
> mein 32bit Celeron das macht wäre dir ich echt dankbar.

Der kann das von Hause aus. In der Floatingpoint Unit des Celeron gibt 
es den 64Bit Integertype. Das konnten damals schon die 8087 
Coprozessoren.

Gruss Helmi

von Mike B. (sunmils)


Lesenswert?

ok, vielen Dank Leute, besonders an Mark, das hat mir sehr geholfen.

Nur eine kleine Frage noch. Wenn ich nun einen 64bit Rechener hab ist 
die größte Variable ja trotzdem nur 64bit groß. Hier bringt mir die 
andere Architektur dann ja praktisch nur einen Geschwindigkeitsvorteil 
bei entsprechend großen Variablen, sonst nichts? Typen Größer 64bit, 
also 128 in dem Fall, gibt es ja nicht.

von D. I. (Gast)


Lesenswert?

Mike B. schrieb:
> ok, vielen Dank Leute, besonders an Mark, das hat mir sehr geholfen.
>
> Nur eine kleine Frage noch. Wenn ich nun einen 64bit Rechener hab ist
> die größte Variable ja trotzdem nur 64bit groß. Hier bringt mir die
> andere Architektur dann ja praktisch nur einen Geschwindigkeitsvorteil
> bei entsprechend großen Variablen, sonst nichts? Typen Größer 64bit,
> also 128 in dem Fall, gibt es ja nicht.

Größerer Adressbereich -> mehr Arbeitsspeicher adressierbar

von Mike B. (sunmils)


Lesenswert?

Christopher D. schrieb:
> Größerer Adressbereich -> mehr Arbeitsspeicher adressierbar

schon klar, aber hierum ging es mir in dem Moment nicht

von Mark .. (mork)


Lesenswert?

>Nur eine kleine Frage noch. Wenn ich nun einen 64bit Rechener hab ist
>die größte Variable ja trotzdem nur 64bit groß. Hier bringt mir die
>andere Architektur dann ja praktisch nur einen Geschwindigkeitsvorteil
>bei entsprechend großen Variablen, sonst nichts?

Letztendlich ja. Wenn Du nur mit 32 Bit rechnen musst und beide CPUs 
gleich schnell sind, hat eine 64-Bit CPU keinen Vorteil gegenüber einer 
32-Bit CPU. Der Grund, warum momentan trotzdem auf 64-Bit umstiegen 
wird, ist der von Mike genannte größere Adressbereich.

> Typen Größer 64bit, also 128 in dem Fall, gibt es ja nicht.

Nicht in C (zumindest keinen ganzzahligen). Aber in Assembler z.B. kann 
man mit beliebig großen Typen rechnen.

von Mark .. (mork)


Lesenswert?

Nachtrag: Sollte natürlich 'Christopher' und nicht 'Mike' in meinem 
letzten Posting heißen. Hab mich verguckt^^

von ... ... ... (Gast)


Lesenswert?

Mark .. schrieb:
>> Typen Größer 64bit, also 128 in dem Fall, gibt es ja nicht.
>
> Nicht in C (zumindest keinen ganzzahligen). Aber in Assembler z.B. kann
> man mit beliebig großen Typen rechnen.
Äh unter Assembler müsstest du dir den 128-Bit-Datentyp zusammenbasteln, 
und was spricht dagegen, dass gleiche nicht unter C zu tun/können?

von Michael B. (mb_)


Lesenswert?

... ... ... schrieb:
> Mark .. schrieb:
>>> Typen Größer 64bit, also 128 in dem Fall, gibt es ja nicht.
>>
>> Nicht in C (zumindest keinen ganzzahligen). Aber in Assembler z.B. kann
>> man mit beliebig großen Typen rechnen.
> Äh unter Assembler müsstest du dir den 128-Bit-Datentyp zusammenbasteln,
> und was spricht dagegen, dass gleiche nicht unter C zu tun/können?

Naja, in Standard-C geht das nicht so ohne Weiteres, weil man keinen 
direkten Zugriff auf die carry-flags hat. Der GCC hat aber 
beispielsweise eine Erweiterung um Typen größer 64bit zu definieren.

von D. I. (Gast)


Lesenswert?

hat C# nicht einen 128bit Datentyp :x und im Zweifel Java BigInteger / 
BigDecimal duck und weg

von Rolf M. (rmagnus)


Lesenswert?

Mike B. schrieb:
> ok, habs getestet mit:
>
> long long int a,b=4294967296;
> a=b+1;
> printf("4294967296 + 1 = %lld",a);
>
> und es funzt tatsächlich. War mir neu. Wenn du mir noch sagen kannst wie
> mein 32bit Celeron das macht wäre dir ich echt dankbar.

Wie würdest du es selber machen, und warum denkst du, daß es dem 
Compiler technisch völlig unmöglich ist, sowas intern schon für dich zu 
tun?

Mike B. schrieb:
> Christopher D. schrieb:
>> Größerer Adressbereich -> mehr Arbeitsspeicher adressierbar
>
> schon klar, aber hierum ging es mir in dem Moment nicht

Das ist aber der eine wirkliche Vorteil einer 64-Bit-Architektur. 
64-Bit-Berechnungen kommen nicht so häufig vor, daß sich dadurch ein 
signifikanter Geschwindigkeitsvorteil ergäbe.

Helmut Lenzen schrieb:
> Mike B. schrieb:
>> Wenn du mir noch sagen kannst wie
>> mein 32bit Celeron das macht wäre dir ich echt dankbar.
>
> Der kann das von Hause aus. In der Floatingpoint Unit des Celeron gibt
> es den 64Bit Integertype. Das konnten damals schon die 8087
> Coprozessoren.

Nein. Integertypen gab es beim 8087 nicht und genausowenig gibt's die in 
der FPU irgendeines anderen x86-Prozessors.

von (prx) A. K. (prx)


Lesenswert?

Rolf Magnus schrieb:

> Nein. Integertypen gab es beim 8087 nicht und genausowenig gibt's die in
> der FPU irgendeines anderen x86-Prozessors.

Die 8087 kannte in der Load und Store Befehlen neben den 
Fliesskommadatenformaten auch 32- und 64-Bit Integers und ein 
BCD-Format. Infolgedessen stecken diese Formate bis heute in den 
x87-Implementierungen drin. Mit entsprechender Einstellung der FPU waren 
die Rechnungen auch entsprechend der üblichen Konvention exakt.

Es war allerdings insgesamt eher ineffizient, für 32-Bit "long" Daten 
auf 8087 Befehle auszuweichen, daher wurde das von Compilern überwiegend 
nur für Datenkonvertierung genutzt.

von Helmut L. (helmi1)


Lesenswert?

64 Bit Integer Addtion ueber 8087

fild qword ptr[Wert1]           ;1. Integer Wert laden
fild qword ptr[Wert2]           ;2. Integer Wert laden
faddp st(1),st                  ;Addition + Pop Stack
fistp qword ptr[Ergebnis]       ;Store Integer Wert und Pop Stack

von Rolf M. (rmagnus)


Lesenswert?

Naja, gut. Man kann beim Laden einen Integer nacht floating point 
konvertieren. Aber ich wäre nie auf die Idee gekommen, über diesen Umweg 
zwei Integer zu addieren.

von Mike B. (sunmils)


Lesenswert?

Rolf Magnus schrieb:
> Mike B. schrieb:
>> ok, habs getestet mit:
>>
>> long long int a,b=4294967296;
>> a=b+1;
>> printf("4294967296 + 1 = %lld",a);
>>
>> und es funzt tatsächlich. War mir neu. Wenn du mir noch sagen kannst wie
>> mein 32bit Celeron das macht wäre dir ich echt dankbar.
>
> Wie würdest du es selber machen, und warum denkst du, daß es dem
> Compiler technisch völlig unmöglich ist, sowas intern schon für dich zu
> tun?

ok, im Nachhinein scheint es mir auch logisch. Hatte nur, von der etwas 
länger zurückliegenden Informatik Vorlesung, etwas anderes in 
Erinnerung. Das hat sich halt über die Zeit so festgesetzt. Und bisher 
sah ich darin auch den signifikantesten Vorteil einer 64bit CPU.

Das Prinzip generell kannte ich eigentlich schon vom uC, wo es ja im 
wesentlichen auch nicht anders gemacht wird.

von Karl H. (kbuchegg)


Lesenswert?

Mike B. schrieb:
> sorry, muss nochmal genau nachfragen, denn unser prof hat uns da glaub
> ich was anderes erzählt. Du meinst also, das z.B. ein 32bit Rechner von
> der Architektur so gebaut ist, das er Berechnungen mit Operanden größer
> als 32bit auf mehrere Berechnungen aufteilt und später dann in einer
> Variable zusammenfügt. Also max. 64bit bei long long??

Was überrascht dich daran so sehr?
Als Kleinkind hast du das kleine Einmal Eins gelernt.
Deine 'Hardware' kann also Multiplikationen bis zu 10*10. Und nachdem du 
das gelernt hast, hat dir deine Lehrerin gezeigt, wie man mit diesem 
Grundwissen jede beliebige Multiplikation durchführen kann.

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.