7.8 Festkomma in String umwandeln

Gast #3216849
Lesenswert?

Hallo,
um eine vorzeichenbehaftete 7.8 Festkommazahl auf einem avr in einen 
String umzuwandeln, habe ich folgende Funktion gebastelt.
Ich würde mich über konstruktive Kritik an der Funktion freuen.

Gibt es noch eine einfachere Möglichkeit, die Umwandlung vorzunehmen?

Viele Grüße
Michael
1
#include <avr/io.h>
2
#include <string.h>
3
#include <stdlib.h>
4

5
void Q7p8toString(char * str, uint16_t number, uint8_t nachkommastellen) {
6

7
  str[0] = 0;
8
  
9
  if (!(number & 0x8000)) {
10
    // positiv    
11
  } else {
12
    // negativ
13
    number = (~number) + 1;
14
        
15
    // Minus einfügen
16
    strcat(str, "-");
17
  }
18
  
19
  // Vorokmmaanteil
20
  volatile uint16_t vorkomma = number >> 8;
21
  char hilf [4];
22
  itoa(vorkomma,hilf,10);
23
  strcat(str,hilf);
24
  
25
  // Vorkommaanteil löschen
26
  number = number & 0x00FF;
27
  
28
  // Komma
29
  uint8_t strpos = 0;
30
  strpos = strlen(str);
31
  str[strpos] = ',';
32
  strpos++;
33
  str[strpos] = 0;
34

35
  
36
  // Nachkommaanteil
37
  for (int i=0; i<nachkommastellen; i++) {
38
    number = number * 10;
39
    uint8_t stelle = number >> 8;
40
    
41
    // Stelle anhängen
42
    str[strpos] = 0x30+stelle;
43
    strpos++;
44
    str[strpos] = 0;
45
    
46
    number = number &0x00FF;
47
  }
48
}
#3217074
Lesenswert?

Der Teil mit den Nachkommastellen ist vermutlich nicht das, was du 
erreichen willst. 0xFF sollte ja wohl auf ,996094... abbilden.

Wenn genug Flash-Speicher zur Verfügung steht, würde ich wohl auf 
(s)printf zurückgreifen. Ansonsten muss man den Wert mit so etwas wie 
9961 multiplizieren und durch 255 teilen und dann erst in Zeichen 
umwandeln. Mit 16-Bit kommt man da aber nicht mehr hin.
Gast #3217078
Lesenswert?

michael schrieb:
> if (!(number & 0x8000)) {
>     // positiv
>   } else {
>     // negativ
>     number = (~number) + 1;
>
>     // Minus einfügen
>     strcat(str, "-");
>   }

warum nicht lesbar schreiben?

if ( number < 0 ) ...


>   // Vorokmmaanteil
>   volatile uint16_t vorkomma = number >> 8;
was soll das volatile hier?

> str[strpos] = 0x30+stelle;
auch das kann man lesbar schreiben

str[strpos] = '0' + stelle;
Gast #3218439
Lesenswert?

michael schrieb:
> Gibt es noch eine einfachere Möglichkeit, die Umwandlung vorzunehmen?

Ja.
Vermutlich ist fast alles andere einfacher und effektiver als dein Code.
Ich hatte vor geraumer Zeit mal eine meiner Libs für e/a-Konvertierungen 
gepostet, mußt mal suchen (oder conv.c aus der Lernbetty nehmen). Für 
den ganzen Teil kannst du dort fündig werden.

Für den gebrochenen Teil geht das anders:
1.  zuerst den ganzen Teil wegschneiden und ausgeben
1a. nen Punkt ausgeben
2.  dann Zahl * 10 nehmen
3.  ganzen Teil als Ziffer ausgeben und dann wegschneiden
Punkt 3 so oft wiederholen, wie du magst.

W.S.

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