64bit-zahlen mit openbsd

dettus

Bicycle User
hi.
weiss irgendwer, wie ich es schaffe mit printf 64-bitzahlen vernuenftig auszugeben? und mit denen auch anstaendig zu rechnen?

mein erstes gebastel in dieser richtung sah naemlich so aus:
Code:
dettus@h9291:[~/prog/c]cat test.c
#include <stdio.h>
#include <stdlib.h>

int main (void)
{


        int64_t l=0xFEDCBA9876543210;
        int64_t m=0x00000000FFFFFFFF;
        printf("%x:%x %x\n",l>>32,(l&m),l);
        return 0;
}

dettus@h9291:[~/prog/c]gcc -o test test.c
dettus@h9291:[~/prog/c]./test
fedcba98:ffffffff 76543210

das hat mich persoenlich etwas entmutigt: die operation l&m, die eigentlich die untersten 32 bit aus der zahl schneiden sollte, scheint nicht ganz das zu tun, was sie sollte.... (das korrekte ergebnis waere 76543210...)
wie sieht das dann erst fuer additionen und multiplikationen aus?
ach ja, mein betriebssystem auf der kiste ist openbsd 3.5.
 
Wie doch mein alter Chemielehrer jetzt wohl sagen würde:

Eii, jetzt sitzt aber das printf() in der Ecke und heult. :ugly:

Wenn du dir die Speichernutzung von printf ansiehst, wirst du feststellen, dass der mehr als genug Daten zum Ausgeben hat (Er hat sogar zu viele!). Deine Operationen werden nicht so ausgegeben, wie man sich das jetzt denken würde. Folgendes Programm wäre vom speichertechnischen her korrekt:

Code:
$ cat test.c
#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
        int64_t l = 0xFEDCBA9876543210;
        int64_t m = 0x00000000FFFFFFFF;
        printf("%x:%x %x:%x %x:%x\n", l>>32, (l&m), l);
        return 0;
}
$ gcc -o test test.c
test.c: In function `main':
test.c:7: warning: integer constant is too large for "long" type
$ ./test
fedcba98:ffffffff 76543210:0 76543210:fedcba98
$ _

Und dabei sieht man schon die Problematik bei printf mit 32-Bit-Ausgabe von 64-Bit-Zahlen (upside down). Um das ganze zu umgehen, verwende einfach "%llx" für 64-Bit-Ausgabe ("%llx" ist allerdings nicht teil von "ISO C90" :rolleyes: ):

Code:
$ cat test.c
#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
        int64_t l = 0xFEDCBA9876543210;
        int64_t m = 0x00000000FFFFFFFF;
        printf("%llx %llx %llx\n", l>>32, (l&m), l);
        return 0;
}
$ gcc -o test test.c
test.c: In function `main':
test.c:7: warning: integer constant is too large for "long" type
$ ./test
fffffffffedcba98 76543210 fedcba9876543210
$ _

Falls es wichtig sein sollte (wegen der C-Warnung):

Code:
$ uname -prs
OpenBSD 3.7 Intel Pentium II ("GenuineIntel" 686-class, 512KB L2 cache)
 
Du kannst auch einfach das 64-bit Argument nach (long) casten, dann werden allerdings die oberen 32 bit entsorgt (also FEDCBA98 statt
FFFFFFFFFEDCBA98).

BTW: long long als Typ geht auch, und wenn man hinter der Konstanten zwei "L" spendiert, dann entfaellt auch die Warnung beim compilieren.
 
Zurück
Oben