Forum: Mikrocontroller und Digitale Elektronik Ziffern hinter dem Komma extrahieren


von Rush .. (rush)


Lesenswert?

Mahlzeit community ;-)

Kann mir jemand sagen wie ich die Ziffern hinter dem Komma auslesen 
kann?
Hintergrund ist, ich wollte mir eine Fkt. schreiben welche mir die 
Stellen einer Zahl zählt

Ich dachte mir folgendes:
zum Beispiel 123. Ich "teile" durch 10.
Wären dann 12,3. Dann will ich aber nur die die 3 aus dem ergebnis 
weiterverarbeiten und zwar in der hinsicht dass ich sie mit der 
eigentlichen Zahl vergleiche. Stimmen beide nicht überein, teile ich 
beim nächsten schleifendurchgang durch 100. Wären hinterm komma 23 usw.
beim letzten Durchgang würde der Zustand 123=123 eintreten und die 
schleife beendet werden.
Ja, und bei jedem schleifendurchgang dann eben noch einen zähler 
mitlaufen lassen dessen wert zurückgegeben wird.

Das ganze in C.

Mein Problem ist im Grunde genommen nur das, dass ich nicht weiss wie 
ich aus einer Kommazahl die "Zahl" hinter dem Komma extrahiere.

Hoffe ihr versteht was ich hier geschrieben habe, kommt mir irgendwie 
verwirrend vor ;-)

Danke

von Achim M. (minifloat)


Lesenswert?

Rush ... schrieb:
> wie
> ich aus einer Kommazahl die "Zahl" hinter dem Komma extrahiere.

Kannst ja erst Modulo benutzen, das gibt dir den Rest.

z.B.
1
int meinezahl = 123;
2
int meinteiler = 100;
3
int ergebnis;
4
float nachkomma;
5
6
ergebnis = meinezahl % meinteiler;
7
8
nachkomma = (float) ergebnis / meinteiler;

"nachkomma" sollte jetzt den Wert 0.23 haben.

mfg mf

von Achim M. (minifloat)


Lesenswert?

Modulo selber implementiert:
1
int meinezahl = 753;
2
int meinteiler = 100;
3
int ergebnis = meinezahl;
4
5
while(ergebnis => meinteiler)
6
{
7
   ergebnis -= meinteiler;
8
}
9
/*"ergebnis" enthält jetzt die Zahl 53*/

mfg mf

PS: das hier ^^ scheint nur mit positiven Zahlen zu gehen.

von Rush .. (rush)


Lesenswert?

nachkomma = (float) ergebnis / meinteiler;

danach steht doch 0,0023 drin. Du meinst wohl * statt teilen oder?

von Rush .. (rush)


Lesenswert?

Da kommt 0 raus. Habe es eben mal ausprobiert

von Achim M. (minifloat)


Lesenswert?

Nein.

123 % 100 = 23

23 / 100 = 0.23

mfg mf

von DirkB (Gast)


Lesenswert?

Warum teilst du nicht einfach solange durch 10, solange die Zahl 
ungleich Null ist.
1
int anz = 0
2
while (zahl != 0)
3
{ zahl/=10;
4
   ++anz;
5
}
oder
1
for (anz = 0; zahl != 0; zahl/=10, ++anz);

von Achim M. (minifloat)


Lesenswert?

Rush ... schrieb:
> Da kommt 0 raus

auch auf float gecasted? sonst kommt tatsächlich 0 raus.

Da du modulo 100 rechnest, könntest du auch die 23 direkt als 
Nachkommaanteil benutzen.

mfg mf

von Rush .. (rush)


Lesenswert?

1
int anz = 0
2
while (zahl != 0)
3
{ zahl/=10;
4
   ++anz;
5
}

Hierbei rennt das Programm aus irgendeinem grund in eine Endlosschleife 
rein.

von Walter S. (avatar)


Lesenswert?

Rush ... schrieb:
> Hintergrund ist, ich wollte mir eine Fkt. schreiben welche mir die
> Stellen einer Zahl zählt

wieso erinnert mich diese Frage eigentlich an Schule?

von DirkB (Gast)


Lesenswert?

Ich bin von davon ausgegangen, das zahl ein int ist (wegen 123)

von log10 (Gast)


Lesenswert?

Problematisch am Eröffnungsbeitrag ist, dass die eigentliche 
Fragestellung ("Anzahl der Stellen einer Zahl ermitteln") und der 
vermeintliche Lösungsansatz ("Ziffern hinter dem Komma extrahieren") 
vermischt werden. Dadurch sind die Antworten direkt in Richtung 
Modulorechnung gegangen, was hier nicht unbedingt eine "sinnvolle" 
Lösung darstellt.

"Mathematisch korrekt" ermittelt man die Anzahl der Stellen einer Zahl 
nämlich mit der Logarithmusfunktion:
1
unsigned stellen(int i)
2
{
3
 if (i == 0)
4
   return 1;
5
 else
6
   return log10(abs(i)) + 1;
7
}

Den algorithmischen Ansatz von DirkB kann man natürlich auch verfolgen, 
dann muss man sich aber schon mehr Gedanken machen (der Algorithmus von 
DirkB hat gleich mehrere Fehler).

von Achim M. (minifloat)


Lesenswert?

Rush ... schrieb:
> Hintergrund ist, ich wollte mir eine Fkt. schreiben welche mir die
> Stellen einer Zahl zählt

hmm, das geht auch ganz anders:
1
char mystring[20];
2
int meinezahl = 12345;
3
int laenge;
4
5
sprintf(mystring, "%d", meinezahl);
6
7
laenge = strlen(mystring);
;) mf

PS: falls die Zahl negativ sein kann, noch das hier vor sprintf(); rein 
werfen:
1
meinezahl = (meinezahl < 0) ? 0 - meinezahl : meinezahl;

PPS: Ich hab meinen Informatik Profs in den Praktikumsaufgaben immer 
möglichst abstruse Lösungen abgegeben. Kommentar der Profs dazu war 
meist: "Na, wenigstens sehe ich, dass Sie nicht wie die restlichen 90% 
des Kurses einfach alles aus meinen Musterlösungen herauskopieren."

von Achim M. (minifloat)


Lesenswert?

herauskopieren? -> abstrus!

von Rush .. (rush)


Lesenswert?

Die sache mit dem Log funktioniert auch nicht. Da wird garnichts 
ausgegeben, nicht einmal eine Null.

Ich hänge die paar zeilen einfach mal dran:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
unsigned int mod(unsigned int zahl)
5
{
6
 unsigned int i = zahl;
7
 if (i == 0)
8
   return 1;
9
 else
10
   return log10(abs(i)) + 1;
11
12
}
13
14
int main(int argc, char *argv[])
15
{
16
    unsigned int bla = 123;
17
    printf("%u" + mod(bla));
18
   
19
    system("PAUSE");  
20
    return 0;
21
}

von Achim M. (minifloat)


Lesenswert?

Für Mathematikfunktionen musst du die math.h einbinden.
mfg mf

von log10 (Gast)


Lesenswert?

Rush ... schrieb:
> Die sache mit dem Log funktioniert auch nicht. Da wird garnichts
> ausgegeben, nicht einmal eine Null.

Dein Code ist, mit Verlaub, auch völlige Grütze. Vielleicht solltest du 
erstmal ein gutes C-Buch durcharbeiten. Darin sollte dann z.B. erklärt 
werden, wie man die printf-Funktion korrekt benutzt.

Du kannst nicht erwarten, dass wir dir hier deine Hausaufgaben machen. 
Ein bisschen Eigeninitiative darf wohl schon von dir gefordert werden.

von Rush .. (rush)


Lesenswert?

Das erwarte ich auch garnicht!
Schließlich mache ich mir meine Gedanken darüber sonst hätte ich auch 
keinen Ansatz gepostet.

Die Sache mit der math.h habe ich schlicht und ergreifend übersehen.

Aber auch nach dem Einbinden passiert rein garnichts :-(

von Karl H. (kbuchegg)


Lesenswert?

Rush ... schrieb:

> Aber auch nach dem Einbinden passiert rein garnichts :-(

Das wundert mich ehrlich gesagt aber auch nicht wirklich

    printf("%u" + mod(bla));

Tja. Das funktioniert nun mal nicht so.

> Schließlich mache ich mir meine Gedanken darüber

Gedanken machen ist guuuuut. Aber ehe du dir Gedanken machst, kommt noch 
ein Schritt davor. Und der lautet: Erlernen der absoluten Basics. Und 
dazu kann man sich auch Gedanken machen, nämlich wenn man darüber 
nachdenkt, was man gerade in seinem C-Buch gelesen hat. Unterschätz das 
nicht!

von eProfi (Gast)


Lesenswert?

Die Fragestellung ist leicht zweideutig, ich dachte zuerst auch, Rush 
wollte die einzelnen Stellen extrahieren. Das mache ich immer so 
(endlich mal eine Anwendung für den Komma-Operator):

c='0'-1;while(c++,(t-=10000)>=0);putch(c);
c='9'+1;while(c--,(t+= 1000)< 0);putch(c);
c=47;while(c++,(t-=  100)>=0);putch(c);
c=58;while(c--,(t+=   10)< 0);putch(c);
putch(c+48);

Rush will aber die Länge der Zahl haben. Das würde ich mit einer binären 
Suche erledigen, weil am schnellsten:
Nehmen wir an, es ist ein u16_t:

if(i>99){if(i>999){if(i>9999)l=5;else l=4;}else l=3;}
else if(i>9)i=2; else i=1;


ungetestet!

von eProfi (Gast)


Lesenswert?

falsch:
else if(i>9)i=2; else i=1;

soll heißen:
else if(i>9)l=2; else l=1;

von eProfi (Gast)


Lesenswert?

Noch eine Verbesserung:
putch(c+48);

---> putch(t+48);

von faustian (Gast)


Lesenswert?

"Wieso erinnert mich diese Frage eigentlich an Schule?"

Eine Schule die C lehrt ist doch sehr zu empfehlen!

von eAmateur (Gast)


Lesenswert?

eProfi schrieb:
> ---> putch(t+48);

putch(t+'0');

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.