printf uint64_t mit newlib-nano

#3231068
Lesenswert?

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"
Gast #3233011
Lesenswert?

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.
#3233048
Lesenswert?

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
#3234000
Lesenswert?

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.
Moderator Persönliche Seite #3234164
Lesenswert?

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.
#3234227
Lesenswert?

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.
#3234260
Lesenswert?

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 ?
Persönliche Seite #3234295
Lesenswert?

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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren