Wertebereich von uint16_t?

OP #1623970
Lesenswert?

Hallo,

ich stehe etwas auf dem Schlauch:

uint16_t sollte doch einen Wertebereich vom 0 bis 65535 haben.

Bei mir reicht es aber nur bis 2^15, d.h., wenn ich eine größere Zahl 
per UART übertrage, dann ist bei 32767 Schluß, danach kommt ein 
Minuszeichen und es zählt wieder rückwärts - wie es bei einem signed 
geschieht.

Kann denn der gcc-Compiler mein uuuu-int16_t nicht lesen?

Gruß
Alexander
Gast #1623980
Lesenswert?

Alexander Schmeil schrieb:
> wenn ich eine größere Zahl
> per UART übertrage,

Das deutet darauf hin, das Du bei der Vorbereitung für die Übertragung 
oder beim speichern auf der Empfängerseite was anderes machst als es 
Deine Absicht ist. Gib uns diesbezüglich Details und Code.
OP #1624021
Lesenswert?

Glaube ich auch, ich habe probeweise die Definition des Array auf 
uint32_t geändert und trotzdem bleibt die Begrenzung bei 2^15.

Also, es ist in einem Programm-Module ein Array definiert mit
int16_t cts[16];.

In einem anderen Modul steht dann
extern uint16_t cts[16];
In dieses Array legt das Programm die ermittelten Werte ab, im 
vorliegenden Testfall habe ich die Werte um 32367 manuell eingetragen.

Dann kommt die Ausgabe über UART

char mw_ascii[5];  // Ascii-Wert von cts[i]
itoa(cts[i], mw_ascii, 10);
uart_puts(mw_ascii);

Beim Schreiben dieser Antwort ist mir aufgefallen, was ich falsch 
gemacht habe: das Nadelöhr ist wohl die Definition der Variablen 
mw_ascii[],
wo es an der nötigen Bandbreite fehlt.

Ich glaube, wenn ich das ändere, wird es funktionieren.

Gruß
Alexander
Gast #1624031
Lesenswert?

Alexander Schmeil schrieb:
> int16_t cts[16];.

Häh. Ich dachte uint16?

Alexander Schmeil schrieb:
> In einem anderen Modul steht dann
> extern uint16_t cts[16];

Hmm. An sich würde ich vom Linker erwarten, das er meckert weil die 
Typen nicht übereinstimmen. Denn uint16_t ist ungleich int16_t.
Ändere das, das ist sauberer.

Der eigentliche Knackpunkt aber wird die Verwendung von itoa sein. Lies 
Dir mal die Beschreibung durch. Es erwartet ein int und kein unsigned 
int. Entsprechend verhält es sich auch. Verwende doch einfach utoa.
OP #1624038
Lesenswert?

Meine Vermutung, es könne an der Variablen mw_ascii liegen, waren 
natürlich unsinnig, für ascii reicht char völlig aus.

Mit utoa statt mit itoa funktioniert es aber bestens!

Vielen Dank für Eure schnelle Hilfe.

Alexander


PS Gibt es irgendwo eine Dokumentation, in der solche Funkltionen und 
ihre Parameter aufgelistet sind? Das itoa() hatte ich seinerzeit nur 
gefunden, weil ich den Namen anderswo schon mal gelesen hatte.
#1624085
Lesenswert?

Rufus t. Firefly schrieb:

> Und da das hier C und nicht C++ ist, haben die Symbolnamen keine
> Typinformation.

Auch in C++ wäre das (zumindest bei GCC) so. Die Symbolnamen werden 
nicht generell um Typinformationen erweitert, sondern nur dort, wo das 
nötig ist, z.B. bei Funktionen, wo man Parameter-Typen für die 
Überladung unterscheiden können muß.

Alexander Schmeil schrieb:
> PS Gibt es irgendwo eine Dokumentation, in der solche Funkltionen und
> ihre Parameter aufgelistet sind? Das itoa() hatte ich seinerzeit nur
> gefunden, weil ich den Namen anderswo schon mal gelesen hatte.

Vermutlich in der Dokumentation der Bibliothek, die diese Funktion 
bereitstellt, welche auch immer das sein mag.
Persönliche Seite #1624182
Lesenswert?

> Auch in C++ wäre das (zumindest bei GCC) so.

Du hast natürlich recht, warum auch sollte eine Namensdekoration von 
nicht überladbaren Symbolen erfolgen?

Wobei sie bei solchen Fehlern wie dem hier praktisch wäre.

Der übrigens hätte vermieden werden können, wenn die Headerdatei, in der 
das Array als extern deklariert wurde, in das Modul mit eingebunden 
worden wäre, in dem das Array definiert wird.

Dann hätte der Compiler meckern können.
#1624197
Lesenswert?

Rufus t. Firefly schrieb:

> Du hast natürlich recht, warum auch sollte eine Namensdekoration von
> nicht überladbaren Symbolen erfolgen?
>
> Wobei sie bei solchen Fehlern wie dem hier praktisch wäre.

Wird dadurch nicht besser, im Gegenteil. Dann kriegt man u.U. mehrere 
separate Variablen gleichen Namens und wundert sich, warum die gleiche 
Variable in zwei Programmmodulen unterschiedliche Werte hat. Das ist mit 
Absicht so implementiert.
#1667555
Lesenswert?

bin über die Suche über diesen Thread gestolpert und möchte folgende 
Beobachtung anmerken, die ich mit avr-gcc 4.3.3 mit Target atmega8 
gemacht habe:

itoa auf uint8_t -> liefert 0 - 255, überlauf etc alles scheint ok
itoa auf uint16_t -> liefert -32k - +32k ... Wertebereich wird also 
anders - für *i*toa korrekt - wiedergegeben

also ein bisschen Inkonsistent. Daher ist mir erst bei der verwendung 
von uint16_t Variablen aufgefallen, das ich itoa auf unsigned Variablen 
loslasse. böse! pfui!

utoa auf uint16_t liefert wie erwartet korrekte Ergebnisse.
#1667613
Lesenswert?

Robert F. schrieb:
> bin über die Suche über diesen Thread gestolpert und möchte folgende
> Beobachtung anmerken, die ich mit avr-gcc 4.3.3 mit Target atmega8
> gemacht habe:
>
> itoa auf uint8_t -> liefert 0 - 255, überlauf etc alles scheint ok
> itoa auf uint16_t -> liefert -32k - +32k ... Wertebereich wird also
> anders - für *i*toa korrekt - wiedergegeben
>
> also ein bisschen Inkonsistent.

Nö, überhaupt nicht.
Da ein uint8_t in einen int hineinpasst, und zwar mit allen Werten, ist 
es genau das was zu Erwarten ist.

itoa will einen int!
wenn du einen uint8_t hast, dann wird der zunächst auf einen int 
hochgehoben. Und da das ohne Probleme geht, bleiben alle Werte von 0 bis 
255 erhalten.

Ein uint16_t passt aber nicht mit allen Werten in einen int.

Du gehst davon aus, dass sich itoa irgendwie magisch an den übergebenen 
Parameter anpasst. Das passiert aber nicht. Es wird versucht, das was du 
angibst in einen int zu verwandeln und erst dieser int geht dann an 
itoa. Was du siehst, ist eine direkte Konsequenz dieses impliziten 
Casts.
#1667614
Lesenswert?

Robert F. schrieb:
> itoa auf uint8_t -> liefert 0 - 255, überlauf etc alles scheint ok
> itoa auf uint16_t -> liefert -32k - +32k ... Wertebereich wird also
> anders - für *i*toa korrekt - wiedergegeben
>
> also ein bisschen Inkonsistent.

Genaugenommen ist das nicht inkonsistent.  Da der Prototyp von itoa 
bekannt ist, hast Du in beiden Fällen einen impliziten Cast nach int. 
Und ein Cast (uint8_t) -> (int) geht nunmal unfallfrei, da alle für 
uint8_t möglichen Werte in einen int passen, bei einem (uint16_t) -> 
(int) muss es den beobachteten Überlauf geben.

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