Double auf Display ausgeben!

Gast #3915082
Lesenswert?

Guten Morgen,

ich habe folgende Fkt. die einen Double Wert auf dem Display ausgibt:
1
unsigned char zaehler;
2
double wert;
3

4
void integertodisplay_double(double zahl, unsigned char pos)
5
{
6
    unsigned char zweitenachkommastelle = fmod(zahl*100,10);
7
    unsigned char erstenachkommastelle = fmod(zahl*10,10);
8
    unsigned char einser = fmod(zahl,10);
9
    unsigned char zehner = fmod(zahl/10,10);
10
    unsigned char hunderter = fmod(zahl/100,10);
11
    
12
    integertodisplay_1stellig(zweitenachkommastelle,pos);
13
    pos--;
14
    integertodisplay_1stellig(erstenachkommastelle, pos);
15
    pos--;
16
    integertodisplay_1stellig(einser, pos);
17
    pos--;
18
    if(zehner > 0 || hunderter > 0)
19
    {
20
    integertodisplay_1stellig(zehner,pos);
21
    pos--;
22
    }
23
    if(hunderter > 0)
24
    {
25
    integertodisplay_1stellig(hunderter, pos);
26
    }
27

28
}
29

30
int main()
31
{
32

33
integertodisplay_double(32,10); // klappt wudnerbar
34
zaehler = 16;
35
wert = zaehler*2;
36
integertodisplay_double(wert,10); // dies klappt nicht, meist wird der "Einser" falsch, nämlich gleich Null angezeit
37

38
}

Fällt jemanden auf Anhieb auf, wo hier der Wurm drinsteckt?
Gruß
Gast #3915122
Lesenswert?

es ist ein PIC23 Controller,

fmod macht hoffentlich die "normale" Modulu Operation, habe dazu nur das 
folgende gefunden:
1
math.h:
2
#define __MPROTOL(x)  x ## f
3
#define  fmod(p1,p2) __MPROTOL(fmod)(p1,p2)

nath.h sowie FenericTypeDefs.h sind natürlich inkludiert.
Der Fehler erscheint auch eher unregelmäßig, d.h. die Ausgabe auf dem 
Display wechselt ständig, d.h. mal ist die Ausgabe von 16*2 30 und mal 
32.

Kurios
Gast #3915180
Lesenswert?

Ein Beispiel für double->Display ist in dem Programm 'f_mess.c' zu 
finden.
Beitrag "reziproker Frequenzzähler mit STM32F4Discovery"
Die Funktion 'zeige_x()' ist zwar etwas ausführlicher, als das, was Du 
brauchst, kann aber auf das Notwendige gekürzt werden. Auch wird das 
Ergebnis in einen string gepackt, aber ein Beispiel für eine LCD-Ausgabe 
findet sich weiter unten.
Ich nehme an, daß 'fmod()' Modulo von float liefert; gibt es vielleicht 
eine Funktion 'dmod()'?
Gast #3915224
Lesenswert?

danke für den ganzen Input.

Kann es nicht sein, dass ich noch ein Typcast etc. einfügen muss. Ich 
kenne mich leider nicht genau mit Compilern aus und was dieser intern 
macht:

ein
1
wert = (double)zaehler*2;

hat leider auch keine Beseerung gebracht.
Ich habe ja double = unsigned char * 2;
Wie genau verarbeitet der Compiler das?

Ich habe das Gefühl´, dass irgendwo hier der Hund begraben sein muss.
#3915409
Lesenswert?

u_SD schrieb:
> Wie genau verarbeitet der Compiler das?

bei
1
unsigned char zaehler;
2
double wert;
3
wert = zaehler*2;
 wird zaehler in ein int gewandelt (2 ist schon ein int) und dann als 
Integermultiplikation durchgeführt.
Das Ergebnis (ist auch ein int) wird dann in ein double gewandelt und 
wert zugewiesen.

bei
1
unsigned char zaehler;
2
double wert;
3
wert = (double)zaehler*2;
 werden zaehler und 2 in double gewandelt und dann als 
double-Multiplikation berechnet. Das Ergebnis wird wert zugewiesen.
Gast #3915444
Lesenswert?

> wert = (double)zaehler * 2.0;

Leider ohne Erfolg, trotzdem Danke.

Ich habe mir folgendes mal etwas genauer angeguckt:
1
void integertodisplay_mehrstellig_double(double zahl, unsigned char pos)
2
{
3
    unsigned char zweitenachkommastelle = fmod(zahl*100,10);
4
    unsigned char erstenachkommastelle = fmod(zahl*10,10);
5
    unsigned char einser = fmod(zahl,10);
6
    unsigned char zehner = fmod(zahl/10,10);
7
    unsigned char hunderter = fmod(zahl/100,10);
8
    
9
    integertodisplay_1stellig(zweitenachkommastelle,pos);
10
    integertodisplay_1stellig(erstenachkommastelle, pos);
11
    integertodisplay_1stellig(einser, pos);
12
    if(zehner > 0 || hunderter > 0)
13
    {
14
    integertodisplay_1stellig(zehner,pos);
15
    }
16
    if(hunderter > 0)
17
    {
18
    integertodisplay_1stellig(hunderter, pos);
19
    }
20

21
}

Hierzun hat Herr Brunegg in einem vorherigen Thread mal das folgende 
geschrieben:

> Die Zahl mit 10 multiplizeren, die Zerlegung auf die Einerstelle
> durchführen :-)
>
> Aber Achtung: gegebenenfalls muss bzw. sollte man vorher noch runden.
> Denn 0.1 kann beispielsweise im Rechner nicht gespeichert werden,
> sondern liegt zb als 0.0999999 vor. printf berücksichtigt das und rundet
> entsprechend, so dass die Ausgabe wieder 0.1 lautet, obwohl die im
> Rechner so gar nicht vor liegen.

Was genau hat es damit auf sich?
Wo genau muss ich runden und mit welchen Befehl wäre dies möglich?

Vielen Dank auch an Dirk. Die Ausführungen haben mir sehr geholfen!
#3915535
Lesenswert?

Wohl eher so:
1
void integertodisplay_mehrstellig_double(double zahl, unsigned char pos)
2
{
3
    /* Zuerst das ganze in ein integer umwandeln */
4
    unsigned long longzahl = (long) (zahl * 1000.0);
5

6
    char ziffern[8];
7
    char idx;
8

9
    /* Zerlege longzahl in ziffern - umgekehrte Reihenfolge! */
10
    for(idx = 0; idx < 8; idx ++)
11
    {
12
        ziffern[idx] = longzahl % 10;
13
        longzahl /= 10;
14
    }
15
    
16
    /* Ziffern ausgeben */
17
    for(idx = 0; idx < 8; idx ++)
18
    {
19
        integertodisplay_1stellig(ziffern[7 - idx], idx);
20
    }
21
}
Ohne Gewähr ;-)

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