Forum: Mikrocontroller und Digitale Elektronik Problem mit uint32_t


von Luky (Gast)


Lesenswert?

Ich habe eine Routine um einen 24Bit Wert dezimal darzustellen.
Leider funktioniert das Teil bei größeren Zahlen nicht so wie gewünscht 
und ich komme einfach nicht auf den Fehler... Es werden dann 
irgendwelche Sonderzeichen angezeigt und nicht die Zahlenwerte.
1
void print_number_u24(uint32_t d) {
2
    uint8_t zehner=0, hunderter=0, tausender=0, zehntausender=0, hunderttausender=0, millionste=0, zehnmillionste=0;
3
4
  while ( (uint32_t) d >= 10000000UL) {
5
    d = (uint32_t) d - 10000000UL;
6
    zehnmillionste++;
7
  }
8
  while ( (uint32_t) d >= 1000000UL) {
9
    d = (uint32_t) d - 1000000UL;
10
    millionste++;
11
  }
12
  while ( (uint32_t) d >= 100000UL) {
13
    d = (uint32_t) d - 100000UL;
14
    hunderttausender++;
15
  }
16
  while (d >= 10000) {
17
    d = (uint16_t) d - 10000;
18
    zehntausender++;
19
  }
20
  while (d >= 1000) {
21
    d = (uint16_t) d - 1000;
22
    tausender++;
23
  }
24
  while (d >= 100) {
25
    d = (uint16_t) d - 100;
26
    hunderter++;
27
  }
28
  while (d >= 10) {
29
    d = d - 10;
30
    zehner++;
31
  }
32
33
  uint8_t printzero=0;
34
  if (zehnmillionste) {
35
    print(zehnmillionste);
36
    printzero = 1;
37
  }
38
  if (millionste || printzero) {
39
    print(millionste);
40
    printzero = 1;
41
  }
42
  if (hunderttausender || printzero) {
43
    print(hunderttausender);
44
    printzero = 1;
45
  }
46
  if (zehntausender || printzero) {
47
    print(zehntausender);
48
    printzero = 1;
49
  }
50
  if (tausender || printzero) {
51
    print(tausender);
52
    printzero = 1;
53
  }
54
  if (hunderter || printzero) {
55
    print(hunderter);
56
    printzero = 1;
57
  }
58
  if (zehner || printzero) {
59
    print(zehner);
60
  }
61
  print(d);
62
}

von (prx) A. K. (prx)


Lesenswert?

print(0) druckt nicht '0' (=0x30) sondern 0x00.
Also: print('0'+zehner).

von Johannes S. (jhs)


Lesenswert?

Hi!

Was macht den print()?

Außerdem halte ich deine ganzen casts (uint32t, uint16t) für 
überflüssig.

Gruß
Johannes

von Karl H. (kbuchegg)


Lesenswert?

darf ich fragen warum du nicht einfach ultoa benutzt?

(Und schmeiss die casts raus. Die braucht kein Mensch)

von Jean (Gast)


Lesenswert?

>while (d >= 10000) {
>    d = (uint16_t) d - 10000;
>    zehntausender++;
>  }

Das geht in die Hose, was machste wenn die vorherige Zahl z.B. 190.000 
war und du 100.000 abziehst. Dann castest du 90.000 nach uint16 uund du 
schneidest die oberen Bytes ab.

Gruß

von (prx) A. K. (prx)


Lesenswert?

Solche Konvertierungen sind übrigens rückwärts effizienter. Die Ziffern 
von rechts nach links konvertieren und anschliessend per strrev 
umdrehen.

von Luky (Gast)


Lesenswert?

Mein print addiert selber '0'. Das funktioniert schon. Und für 16Bit 
Zahlen geht das Ganze ja auch. Nur wenn ich eine 32Bit Zahl umwandeln 
will läufts schief...
Für Alternativen bin ich aber immer offen, mit ultoa habe ich auf dem 
AVR noch nie herumgespielt. Mal probieren...

von Robert L. (manateemoo)


Lesenswert?

Vielleicht hilfts

#include "stdafx.h"

#define byte  unsigned char
#define word  unsigned short
#define dword  unsigned int

void dword2string(dword dwNbr,char * pString)
{
  dword dwDigit;
  dword dwDivisor = 1000000000;  //because range 0..4294967296
  bool boShowZero = false;

  while(dwDivisor)
  {
    dwDigit = dwNbr / dwDivisor;
    dwNbr -=  dwDigit * dwDivisor;
    dwDivisor /= 10;
    if ( (0 != dwDigit) || ( true == boShowZero ) )
    {
      *pString = dwDigit + '0';
      pString++;
      boShowZero = true;
    }
  }
  *pString = 0;
}


char mySting[12];

int main(void)
{
  dword2string(123056,mySting);
  printf(mySting);

  return 0;
}

von Karl H. (kbuchegg)


Lesenswert?

Luky schrieb:
> Mein print addiert selber '0'. Das funktioniert schon. Und für 16Bit
> Zahlen geht das Ganze ja auch. Nur wenn ich eine 32Bit Zahl umwandeln
> will läufts schief...

Was jetzt?
Weiter oben war noch von maximal 24 Bit die Rede.
Du hast in deinem Code keinerlei Vorkehrungen getroffen, wenn die Zahl 
größer als 99999999 wird.

von Luky (Gast)


Lesenswert?

@Karl heinz Buchegger:
Ja ein 24Bit ADC spuckt halt 24 Bit aus, die muss man aber leider in 
32Bit abspeichern da es kein uint24_t gibt.
Trotzdem kommen da keine Zahlen > 16777216 raus...
Das ist aber nicht das Problem. Das Problem entsteht sobald die Zahl 
größer 2^16 wird...

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.