Forum: Mikrocontroller und Digitale Elektronik Nachkommastellen in c verwenden


von Dirk (Gast)


Lesenswert?

Hallo,

ich möchte unter c die Nachkommastellen einer double abtrennen und 
verwenden. Ich kann aber nicht sagen wie viele Nachkommastellen ich 
habe. Das kann sich immer ändern.

Gibt es dafür eine Funktion, oder wie kann man sowas lösen?

double test = 42.123456789;
uint test1 = (uint)test = 42;
uint test2 = ??? = 123456789;

Dirk

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Dirk schrieb:
> double test = 42.123456789;

nachkomma = test - atoi( test);

von Fragezeichen (Gast)


Lesenswert?

Als Idee: Den Int-Teil durch Subtraktion abtrennen und die 
Nachkommastellen in einer Schleife mit 10 multiplizieren bis der neuer 
Int-Wert gleich dem (Rest-)Double-Wert ist

von Walter S. (avatar)


Lesenswert?

Joachim Drechsel schrieb:
> nachkomma = test - atoi( test);

gar nicht! atoi heißt ASCI to integer

von Dirk (Gast)


Lesenswert?

Joachim Drechsel schrieb:
> nachkomma = test - atoi( test);

atoi() macht aus einem String ein int. Ich habe keinen String. Oder was 
meinst Du?

von Dirk (Gast)


Lesenswert?

Fragezeichen schrieb:
> Als Idee: Den Int-Teil durch Subtraktion abtrennen und die
> Nachkommastellen in einer Schleife mit 10 multiplizieren bis der neuer
> Int-Wert gleich dem (Rest-)Double-Wert ist

Hab ich auch schon überlegt. ist aber recht aufwändig.

von Walter S. (avatar)


Lesenswert?

Dirk schrieb:
> Ich kann aber nicht sagen wie viele Nachkommastellen ich
> habe.

da musst du dich auf die ANzahl festlegen,

von Peter II (Gast)


Lesenswert?


von reimay (Gast)


Lesenswert?

double modf (double x, double* intpart);




Break into fractional and integral parts
 Breaks x into an integral and a fractional part.

The integer part is stored in the object pointed by intpart, and the 
fractional part is returned by the function.

Both parts have the same sign as x.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Walter S. schrieb:
> da musst du dich auf die ANzahl festlegen,

Nicht notwendig.

So gehts:
1
  double test = 42.123456789;
2
  unsigned int test1;
3
  char s[30];
4
5
  test1= atoi(strchr((snprintf(s,sizeof(s),"%f",test),s),'.')+1);
(sofern garantiert ist, dass es überhaupt Nachkommastellen gibt)

Aber wie Walter S. schon schreibt: mit fester Anzahl wärs einfacher.

von Florian (Gast)


Lesenswert?


von reimay (Gast)


Lesenswert?

ups, sehe gerade zu spät.
so wirds angewendet:

    double std = kommen_std + (kommen_min/60.0) + 7.75;
    gehen_min = modf (std,&gehen_std);
    gehen_min = 60.0 * gehen_min;

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Walter S. schrieb:
> Joachim Drechsel schrieb:
>> nachkomma = test - atoi( test);
>
> gar nicht! atoi heißt ASCI to integer

'tschullung. Zu kurz gedacht und zu früh abgeschickt.

nachkomma = test - (int) test;

von Karl (Gast)


Lesenswert?

Was willst du den dann mit den Nachkommastellen anfangen, wenn du nicht 
weißt, wieviele es werden?

von Walter S. (avatar)


Lesenswert?

Markus Weber schrieb:
> test1= atoi(strchr((snprintf(s,sizeof(s),"%f",test),s),'.')+1);

das gibt aber immer eine feste Anzahl von Nachkommastellen, also
z.B. 1.33 ergibt 330000 oder so

der TO sollte erst Mal schreiben was er überhaupt erreichen will

von Dominic A. (neo123)


Lesenswert?

nachkomma = zahl - (int) zahl

von W.S. (Gast)


Lesenswert?

Dirk schrieb:
> Ich kann aber nicht sagen wie viele Nachkommastellen ich
> habe. Das kann sich immer ändern.

Na eben. Das nennt man Gleitkomma-Format. Also ist dein Begehren 
schlichtweg das Abtrennen des ganzen Teiles, womit der Rest - sprich 
alles was Nachkomma ist - übrigbleibt.

double d;
int64  i;
double result;

  i = d;
  result = d-i;

das war's. Jedenfalls dann, wenn d nicht allzu groß ist. Aber den Test 
(if fabs(d) > ...)

W.S.

von Tom (Gast)


Lesenswert?

modf.

Alles andere ist Unfug. float zu int und umgekehrt ist ein potentieller 
Performancekiller. Der Umweg über sprintf wird den nächsten Bearbeiter 
des Codes an Deiner geistigen Gesundheit zweifeln lassen.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Walter S. schrieb:
> Markus Weber schrieb:
>> test1= atoi(strchr((snprintf(s,sizeof(s),"%f",test),s),'.')+1);
>
> das gibt aber immer eine feste Anzahl von Nachkommastellen, also
> z.B. 1.33 ergibt 330000 oder so

Äh... nein. Hast du es mal ausprobiert? Ich geb zu, meine 
Ein-Zeilen-Lösung ist ziemlich bescheuert, ich würde sie so eher nicht 
verwenden und lieber eine Schleife bauen mit *10 bzw. /10. Aber die 
Lösung funktioniert.

> der TO sollte erst Mal schreiben was er überhaupt erreichen will

Da bin ich voll und ganz bei dir. :-)

von Walter S. (avatar)


Lesenswert?

Markus Weber schrieb:
>> das gibt aber immer eine feste Anzahl von Nachkommastellen, also
>> z.B. 1.33 ergibt 330000 oder so
>
> Äh... nein. Hast du es mal ausprobiert?

ja, nachdem du mich verunsicherst jetzt schon:

printf("%f", 1.33);
ergibt
1.330000

von Dirk B. (dirkb2)


Lesenswert?

Das ist aber keine Eigenschaft von der Zahl, sondern von printf.
1
printf("%.2f", 1.333333);

von Wolfgang S. (ws01)


Lesenswert?

Dirk schrieb:

> ich möchte unter c die Nachkommastellen einer double abtrennen und
> verwenden. Ich kann aber nicht sagen wie viele Nachkommastellen ich
> habe. Das kann sich immer ändern.
>
> Gibt es dafür eine Funktion, oder wie kann man sowas lösen?

Das kommt darauf an.

>
> double test = 42.123456789;

Dir ist aber klar, daß 42.123456789 als double gar nicht repräsentierbar 
ist?

Tatsächlich wird der Variablen test hier der Wert 
42.1234567890000022316598915494978427886962890625 zugewiesen. Das wären 
dann 46 Nachkommastellen in der dezimalen Repräsentation.

Lesestoff: https://docs.python.org/2/tutorial/floatingpoint.html

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Walter S. schrieb:
> ja, nachdem du mich verunsicherst jetzt schon:
>
> printf("%f", 1.33);
> ergibt
> 1.330000

Walter, sorry, du hast völlig Recht. printf() hat für die Ausgabe double 
eine voreingestellte Genauigkeit von 6 Nachkommastellen, das hatte ich 
verpennt. :-(

von wire (Gast)


Lesenswert?

Markus Weber schrieb:
> Walter S. schrieb:
>> da musst du dich auf die ANzahl festlegen,
>
> Nicht notwendig.
>
> So gehts:
>   double test = 42.123456789;
>   unsigned int test1;
>   char s[30];
>
>   test1= atoi(strchr((snprintf(s,sizeof(s),"%f",test),s),'.')+1);
>
> (sofern garantiert ist, dass es überhaupt Nachkommastellen gibt)
>
> Aber wie Walter S. schon schreibt: mit fester Anzahl wärs einfacher.

Was soll der ganze Quatsch? Die Funktion nennt sich Frac(), schneidet 
die Vorkommastellen ab, ohne das man durch irgendwelche weiteren 
Kalkulationen den Fehleranteil erhöht.

von Wolfgang S. (ws01)


Lesenswert?

wire schrieb:

> Was soll der ganze Quatsch? Die Funktion nennt sich Frac(), schneidet
> die Vorkommastellen ab, ohne das man durch irgendwelche weiteren
> Kalkulationen den Fehleranteil erhöht.

Eher nicht. Wenn überhaupt, heißt die Funktion aus math.h modf, aber 
auch die liefert den Nachkomma-Anteil als double, nicht wie gewünscht 
als uint, womit wohl "unsigned integer" gemeint sein dürfte.

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.