Forum: Mikrocontroller und Digitale Elektronik 7.8 Festkomma in String umwandeln


von michael (Gast)


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
}

von isnah (Gast)


Lesenswert?

Diese Idee hatte vor 10 Jahren schon jemand anderes:
Beitrag "float to string"
isnah

von B. S. (bestucki)


Lesenswert?

@isnah: Er will Fixkommazahlen umwandeln, nicht Fliesskommazahlen.

Schau mal hier:
Beitrag "Re: [C] Integer in String umwandeln"
Entweder meine Lösung, oder die im nachfolgenden Beitrag verlinkte. Evt. 
kannst du davon was weiterverwenden.

von Detlev T. (detlevt)


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.

von Peter II (Gast)


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;

von W.S. (Gast)


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.

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.