Hallo, ich hab da so ein Problem, eigentlich müsste ich mich ja dafür schämen das ich sowas überhaupt frag, aber ... Versuche ich mit mit newlib-nano und printf ein uint64_t auszugeben bekomme ich nur "lu" als Ausgabe. Laut C99 sollte man ja das PRIu64 Macro verwenden, das funzt allerdings genau so wenig wie %llu. CPU ist ein Cortex-M3, mit der aktuellen gcc-4.7 toolchain von launchpad. Wie geht's denn richtig ? #include <stdint.h> ... uint64_t foo = 42; fprintf(stdout, "Value %llu\r\n", foo ); fprintf(stdout, "Value %"PRIu64"\r\n", foo ); ... Das Ergebnis ist dann: "Value lu" "Value lu"
[f]printf ist Aufgabe der newlib. Der Name "newlib-nano" läßt vermuten, dass diese Inkarnation der newlib nur einen abgespeckten Funktionsumfang mitbringt. Klarkeit schafft das Manual der newlib-nano.
Johann L. schrieb: > Klarkeit schafft das Manual der newlib-nano. Ich würd' ja gerne RTFM machen, aber ich hab bisher absolut NULL brauchbare Doku zur newlib-nano gefunden.
Soweit ich mich errinnere ist long long da nicht unterstützt.
Unsigned ist einfach, zumindest wenn einem eine führende Null nicht
stört.
uint64_t foo = 42;
fprintf(stdout, "Value %u%u\r\n", foo>>32,(uint32_t)foo );
Für Signed braucht es eine Helper Funktion, z.B.
char* l2s(long long v) { static char buff[22]; char*s=buff;
unsigned long l;
if(v<0) v=-v,*s++='-'; if(h=v>>32) s+=sprintf(s,"%u",l); l=v;
sprintf(s,"%u",l); return buff;
}
Wenn du dann Längenbeschränkung usw brauchst, dann kannst du mit %*
arbeiten,
und dies auch der Funktion übergeben.
if(h=v>>32) sollte if(l=v>>32) sein, vielleicht gibt es auch andere Flüchtigkeitsfehler, aber eigentlich sollte das Prinzip klar sein.
chris schrieb: > Unsigned ist einfach, zumindest wenn einem eine führende Null nicht > stört. > uint64_t foo = 42; > fprintf(stdout, "Value %u%u\r\n", foo>>32,(uint32_t)foo ); > Für Signed braucht es eine Helper Funktion, z.B. > > char* l2s(long long v) { static char buff[22]; char*s=buff; > unsigned long l; > if(v<0) v=-v,*s++='-'; if(h=v>>32) s+=sprintf(s,"%u",l); l=v; > sprintf(s,"%u",l); return buff; > } Sorry, aber das ist doch Unsinn. Zur einfacheren Veranschaulichung wende dein Prinzip doch mal auf 16-Bit an (also mit zwei 8-Bit-Ausgaben), und nimm 0x1111 als Beispiel: Was wird angezeigt? 1717 Was wäre richtig? 4369
Naja, ich benutze 0x%x%8.8x , da passt es. Keine Ahnung was mich da geritten hat. Deswegen hier die korrigierte Funktion.
Interessehalber wüßte ich doch gerne, wozu ein Mensch 20-stellige Zahlenmonster ablesen will. Für Datenübertragung würde ich Hex vorziehen, damit kann man beliebig lange Byte-Ströme einfach übertragen.
Peter Dannegger schrieb: > Interessehalber wüßte ich doch gerne, wozu ein Mensch 20-stellige > Zahlenmonster ablesen will. Damit ich sie zu debugging Zwecken mit anderen 20-stelligen Zahlenmonstern vergleichen kann. > Für Datenübertragung würde ich Hex vorziehen, damit kann man beliebig > lange Byte-Ströme einfach übertragen. Mir wär Hex ja auch lieber, aber a) Kann ich im Quellsystem das es anzubinden gilt auch nur dezimal ablesen. b) Trifft das Problem auch auf llx zu.
newlib-nano wurde von den Leuten von ARM als Erweiterung der newlib von Redhat entwickelt, die auch die 'GNU Tools for ARM Embedded Processors' auf launchpad.net mit dieser Laufzeitbibliothek bereitstellen. Fragen dazu also am besten dort stellen. Wurde allerdings schon gefragt und beantwortet: https://answers.launchpad.net/gcc-arm-embedded/+question/219065 und https://answers.launchpad.net/gcc-arm-embedded/+question/220287 Ja, Dokumentation der Änderungen für newlib-nano ist noch dürftig aber im Quellcode der newlib-nano kann man die (Nicht-)Funktionalität nachvollziehen. Quellcode als Archiv auf launchpad und zum Durchklicken auf github (github evtl. nicht aktuell, habe die aktuellen Quellen bisher nicht 'gedifft'). Was spricht dagegen, die absoluten Werte als Päckchen aus hex-Zahlen (dead:beef:cafe:babe) gegenüberzustellen (Differenzen evtl. dann dezimal nach Fallunterscheidung) oder, da es zu "debugging Zwecken" ist, mit der unmodifizierten newlib zu arbeiten? Falls erforderlich, bei den Tests mit einem Controller der gleichen Baureihe aber mehr Speicher.
Martin Thomas schrieb: > Was spricht dagegen, die absoluten Werte als Päckchen aus hex-Zahlen > (dead:beef:cafe:babe) gegenüberzustellen (Differenzen evtl. dann dezimal > nach Fallunterscheidung) Wie schon gesagt, am Quellsystem wo die Daten her kommen seh ich das ganze nur als Dezimalwert im Display und im Zielsystem wo ich mein Progrämmschen laufen hab kann ich sie nicht als Dezimalwert ausgeben. Einen von beiden Werten muss ich wohl händisch umrechnen.
Und was hält dich davon ab, ne eigne, kleine Routine für die Wandlung zum ASCII-Format der Dezimaldarstellung zu schreiben? Der Code ist so einfach, daß es fast peinlich ist, den hier zu posten...
Johann L. schrieb: > Und was hält dich davon ab, ne eigne, kleine Routine für die Wandlung > zum ASCII-Format der Dezimaldarstellung zu schreiben? Davon hält mich nur ab, das ich das Problem mittlerweile anderweitig (Von Hand umrechnen) gelöst habe. > Der Code ist so einfach, daß es fast peinlich ist, den hier zu posten... Du meinst sowas wie weiter oben schon gepostet wurde ?
Heiko Jakob schrieb: > Johann L. schrieb: >> Der Code ist so einfach, daß es fast peinlich ist, den hier zu posten... > Du meinst sowas wie weiter oben schon gepostet wurde ? Was oben steht würde ich schwerlich als Code bezeichnen wollen.
1 | #include <stdint.h> |
2 | #include <stdio.h> |
3 | #include <string.h> |
4 | |
5 | void dump_u64 (uint64_t x) |
6 | {
|
7 | char buf[21 /* = [2 + 64 * ln 2 / ln 10] */], *b = buf; |
8 | |
9 | do
|
10 | {
|
11 | *b++ = '0' + (x % 10); |
12 | x /= 10; |
13 | } while (x); |
14 | |
15 | *b++ = '\0'; |
16 | |
17 | puts (strrev (buf)); |
18 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.