Wo ist der Fehler in diesem Programmcode?

OP #2886179
Lesenswert?
• ▲
▼
Hallo,

ich sitze bestimmt schon 60 Minuten an diesem Problem und bekomme es 
nicht gelöst. Vielleicht kann mir einer von euch helfen. Dazu erst 
einmal folgende Code-Zeilen:

Headerdatei:
1
typedef struct {
2
  ...
3
  unsigned int step_delay;
4
  ...
5
} speedRampData;
6

7
#define T1_FREQ 250000
8
#define SPR 200
9
#define ALPHA (2*3.14159/SPR)
10
#define T1_FREQ_148 (int)((T1_FREQ*0.676)/100)
11
#define A_SQ (long)(ALPHA*2*10000000000)

C-Code Datei:
1
speedRampData srd;
2

3
char buffer[10];
4

5
srd.step_delay = (T1_FREQ_148 * sqrt_Taylor(A_SQ / 100))/100;
6

7
uart_puts("step_delay: ");
8
itoa(srd.step_delay, buffer, 10);
9
uart_puts(buffer);

sqrt_Taylor() ist eine Funktion mit folgendem Prototypen:
1
unsigned long sqrt_Taylor(unsigned long x);

Diese gibt einfach die Wurzel der übergebenen Zahl zurück. In diesem 
Beispiel gibt sie 2507 zurück. Das habe ich auch mit Abfragen überprüft. 
Der Code ergibt so wenig Sinn, habe auch viel der Einfachheit halber mit 
Zahlen ersetzt, damit er besser verständlich ist.

Problem ist, so wie der Code oben steht, sendet er folgende Zeichen ans 
Terminal:
1
step_delay: -23168

Er soll aber:
1
step_delay: 42368

zurückgeben! Was auch passt, wenn es keinen Überlauf geben würde. Wieso 
kommt es zu dem Überlauf? Wieso kann der Compiler eine negative Zahl in 
einer als unsigned int deklarierten Variable abspeichern?

Ich komme da nicht drauf. Ich hoffe, mir kann jemand behilflich sein.

Vielen Dank im voraus
#2886191
Lesenswert?
• ▲
▼
srd.step_delay  ist ein unsigned wert

itoa erwartet aber einen signed wert.

Um unsigned int zu wandeln, willst du die Funktion utoa benutzen.

i   wie integer       ... signed int       (itoa)
u   wie unsigned      ... unsigned int     (utoa)
l   wie long          ... signed long      (ltoa)
ul  wie unsigned long ... unsigned long    (ultoa)


Die Funktionen bilden eine Familie und es liegt an dir, die jeweils zum 
Datentyp passende zu wählen. Ansonsten wird einfach nur das Bitmuster 
hergenommen und passend zum Funktionsnamen ausgewertet. In deinem Fall 
dann eben als signed int.   Also mit Vorzeichen.


> Wieso kann der Compiler eine negative Zahl in einer als
> unsigned int deklarierten Variable abspeichern?

Letzen Endes sind es einfach nur 16 Bits, die abgespeichert werden. Und 
diese 16 Bit können sowohl eine unsigned Zahl (also ohne Vorzeichen), 
aber auch eine signed Zahl (also mit Vorzeichen) repräsentieren. Den 
Bits selber sieht man das aber nicht an, was sie sein sollen. Daher 
musst du die richtige Funktion benutzen. Mit der legst du fest, wie 
diese 16 Bit intepretiert werden sollen: signed oder unsigned.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.