Forum: Mikrocontroller und Digitale Elektronik Festkommadarstellung Zahlen <0,1 fehlerhaft


von Klaus (Gast)


Lesenswert?

Guten Tag,

ich programmiere gerade eine Festkommadarstellung in 32bit. Ich brauche 
3 Vorkomma- und 2 Nachkommastellen(10 Vorkommabits, 22 Nachkommabits). 
Zur Ausgabe habe ich mir diese kleine Routine geschrieben. Diese 
funktioniert soweit auch, allerdings werden Zahlen <0,1 falsch 
ausgegeben. Wenn ich einfach mal mit einer For-Schleife alle Zahlen 
durchprobiere, fängt die Ausgabe bei 0,1 an und nicht bei 0,01. Ich 
finde allerdings den Fehler einfach nicht. Hat hier jemand mit mehr 
Erfahrung eine Idee?

Grüße
Klaus
1
void printInt(int data)
2
{
3
  int Vorkomma = (data & 0xFFC00000) >> 22;  
4
  int Nachkomma = data & 0x3FFFFF;
5
  Nachkomma = ((Nachkomma * 100) + (2097152)) / 4194304;
6
  printf("%d,%d\r\n", Vorkomma, Nachkomma);
7
}

von Leuchtkraft (Gast)


Lesenswert?

Es faengt schon damit an dass:

> 10 Vorkommabits
eben nicht fuer
> 3 Vorkomma- ... stellen
reichen. Da fehlt schon mal das Bit fuer das Vorzeichen.

Ansonsten muss man eine Q10.22 Zahl nur mit ihrem
Skalierungsfaktor multiplizieren, um sie als Gleitkommazahl
zu erhalten.

von A. S. (Gast)


Lesenswert?

Wenn deine Nachkommastellen 10...99 sind, geht es, wenn 0..9, dann fehlt 
die führende 0.

Sie unter printf "%" nach

von Klaus (Gast)


Lesenswert?

ich habe vergessen zu erwähnen, dass ich nur unsigned Integer brauche, 
deshlab sollten 10 Vorkommabits eigentlich reichen, oder? Die Ergebnisse 
sind ja richtig außer wenn ein Ergebnis <0,1 herauskommt.

von Radler (Gast)


Lesenswert?

A. S. schrieb:
> Wenn deine Nachkommastellen 10...99 sind, geht es, wenn 0..9, dann fehlt
> die führende 0.

So schaut das richtig aus:
  printf("%d,%02d\r\n", Vorkomma, Nachkomma);

von Klaus (Gast)


Lesenswert?

Tatsache, vielen Dank für die Antwort. Da hätte ich wahrscheinlich noch 
lange dran gesessen :D.

Schönes Restwochenende

von W.S. (Gast)


Lesenswert?

Klaus schrieb:
> 3 Vorkomma- und 2 Nachkommastellen(10 Vorkommabits, 22 Nachkommabits).

Und dann meinst du, das mit printf zum Schluß zu machen. Hmm...

Hier mal etwas aus dem Stegreif:
(hoffentlich nicht vergaloppiert)
1
 // ganzen Teil ausgeben
2
 tmp = data >> 22;      
3
 Dezi_Out(tmp);
4
 Char_Out(".");
5
6
 // Nachkommastellen ohne Rundung ausgeben
7
 i = 0;
8
 tmp = data & 0x3FFFFF; // gebrochenen Teil abtrennen
9
 while (i<2)            // nur 2 Nachkommastellen machen
10
 { tmp = tmp & 0x3FFFFF; 
11
   tmp = 10 * tmp;
12
   ch = "0" || (tmp >> 22);
13
   Char_Out(ch);
14
   ++i;
15
 }

W.S.

von Radler (Gast)


Lesenswert?

Klaus schrieb:
> Tatsache, vielen Dank für die Antwort. Da hätte ich wahrscheinlich noch
> lange dran gesessen :D.
>
> Schönes Restwochenende

Das ist aber nur die halbe Miete. Du musst noch dafür sorgen, daß die 
'Nachkomma' Variable maximal 2-stellige Werte annehmen kann, sonst wird 
wieder nur Mist angezeigt. Bei deiner Formel geht der Wertebereich bis 
100.

von dfIas (Gast)


Lesenswert?

Radler schrieb:
> So schaut das richtig aus:
>   printf("%d,%02d\r\n", Vorkomma, Nachkomma);
Hmm, müsste das by unsigned nicht besser %u statt %d sein?

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
Noch kein Account? Hier anmelden.