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

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