wake-up-neo.com

Extrahieren Sie den Dezimalteil aus einer Gleitkommazahl in C

Wie können wir den Dezimalteil einer Fließkommazahl extrahieren und den Dezimalteil und den Ganzzahlteil in zwei separate Ganzzahlvariablen speichern?

40
Binu

Sie verwenden die Funktion modf:

double integral;
double fractional = modf(some_double, &integral);

Sie können es auch in eine Ganzzahl umwandeln, aber seien Sie gewarnt, dass die Ganzzahl überlaufen kann. Das Ergebnis ist dann nicht vorhersehbar. 

Versuche dies:

int main() {
  double num = 23.345;
  int intpart = (int)num;
  double decpart = num - intpart;
  printf("Num = %f, intpart = %d, decpart = %f\n", num, intpart, decpart);
}

Für mich produziert es:

Num = 23.345000, intpart = 23, decpart = 0.345000

Was scheint das zu sein, wonach Sie fragen.

41
Chris Bunch

Die schnellste "in a nut Shell" offensichtlichste Antwort scheint:

#define N_DECIMAL_POINTS_PRECISION (1000) // n = 3. Three decimal points.

float f = 123.456;
int integerPart = (int)f;
int decimalPart = ((int)(f*N_DECIMAL_POINTS_PRECISION)%N_DECIMAL_POINTS_PRECISION);

Sie können die Anzahl der Dezimalstellen ändern, indem Sie den N_DECIMAL_POINTS_PRECISION an Ihre Bedürfnisse anpassen.

13

Ich denke, dass die Verwendung von string in diesem Fall der richtige Weg ist, da Sie die Anzahl der Stellen im Dezimalteil nicht a priori kennen. Es funktioniert jedoch nicht für alle Fälle (z. B. 1,005), wie zuvor von @SingleNegationElimination erwähnt. Hier ist meine Meinung dazu:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char s_value[60], s_integral[60], s_fractional[60];
    int i, found = 0, count = 1, integral, fractional;

    scanf("%s", s_value);

    for (i = 0; s_value[i] != '\0'; i++)
    {
        if (!found)
        {
            if (s_value[i] == '.')
            {
                found = 1;
                s_integral[i] = '\0';
                continue;
            }
            s_integral[i] = s_value[i];
            count++;
        }
        else
            s_fractional[i - count] = s_value[i];
    }
    s_fractional[i - count] = '\0';

    integral = atoi(s_integral);
    fractional = atoi(s_fractional);
    printf("value = %s, integral = %d, fractional = %d\n",
        s_value, integral, fractional);

    return 0;
}
3
B. Silva

Ich habe eine Unterroutine erstellt, die einen Double-Float verwendet. Es werden 2 Ganzzahlwerte zurückgegeben.


void double2Ints(double f, int p, int *i, int *d)
{ 
  // f = float, p=decimal precision, i=integer, d=decimal
  int   li; 
  int   prec=1;

  for(int x=p;x>0;x--) 
  {
    prec*=10;
  };  // same as power(10,p)

  li = (int) f;              // get integer part
  *d = (int) ((f-li)*prec);  // get decimal part
  *i = li;
}

void test()
{ 
  double df = 3.14159265;
  int   i,d;
  for(int p=2;p<9;p++)
  {
    double2Ints(df, p, &i,&d); printf("d2i (%d) %f = %d.%d\r\n",p, df,i,d);
  }
}
1
mrwes

Sogar ich dachte darüber nach, wie es geht. Aber ich habe einen Weg gefunden ... probiere diesen Code

printf("Enter a floating number");
scanf("%d%c%d", &no, &dot, &dec);
printf("Number=%d Decimal part=%d", no, dec);

Ausgabe:-

Enter a floating number
23.13
Number=23 Decimal part=13
1
Abi

Verwenden Sie die Gleitkommazahl, um den Wert floor ed zu subtrahieren und den Bruchteil zu erhalten:

double fractional = some_double - floor(some_double);

Dies verhindert das Typumwandeln in eine Ganzzahl, was zu einem Überlauf führen kann, wenn die gleitende Zahl sehr groß ist und ein Ganzzahlwert sie nicht einmal enthalten kann.

Auch für negative Werte gibt dieser Code den positiven Bruchteil von an die gleitende Zahl seit floor ()berechnet den größten ganzzahligen Wert, der nicht größer als der Eingabewert ist .

0
0xAA55
 #include <stdio.h>
Int main ()
{
float f=56.75;
int a=(int)f;
int result=(f-a)*100;
printf ("integer = %d\n decimal part to integer 
 =%d\n",result);
}
Output:- 
integer =56
decimal part to integer = 75
0
Shravani

Angenommen, A ist Ihre ganze Zahl, dann (int) A bedeutet, die Zahl in eine ganze Zahl umzuwandeln und der ganzzahlige Teil zu sein, der andere ist (A - (int) A) * 10 ^ n. Hier ist n die Anzahl der zu haltenden Dezimalstellen .

0
Edahi

Hier ist ein anderer Weg:

#include <stdlib.h>
int main()
{
    char* inStr = "123.4567";         //the number we want to convert
    char* endptr;                     //unused char ptr for strtod

    char* loc = strchr(inStr, '.');
    long mantissa = strtod(loc+1, endptr);
    long whole = strtod(inStr, endptr);

    printf("whole: %d \n", whole);     //whole number portion
    printf("mantissa: %d", mantissa);  //decimal portion

}

http://codepad.org/jyHoBALU

Ausgabe:

whole: 123 
mantissa: 4567
0
dukevin

Wenn Sie nur den ersten Dezimalwert erhalten möchten, ist die Lösung sehr einfach.

Hier ist ein erklärendes Beispiel:

int leftSideOfDecimalPoint = (int) initialFloatValue; // The cast from float to int keeps only the integer part

int temp = (int) initialFloatValue * 10;
int rightSideOfDecimalPoint = temp % 10;

Angenommen, wir haben zum Beispiel einen anfänglichen Gleitkommawert von 27,8. 

  • Indem Sie einfach den anfänglichen Gleitkommawert in ein int umwandeln, verwerfen Sie den Bruchteil und behalten nur den ganzzahligen Teil.
  • Durch Multiplizieren des anfänglichen Float-Werts mit 10 ergibt sich ein Ergebnis von 278,0. Wenn Sie dieses Ergebnis in int konvertieren, erhalten Sie den Wert 278
  • Wenn wir 278 durch 10 teilen, erhalten wir 27,8, von denen der Rest 8 ist. Dies ist der Wert auf der rechten Seite des Dezimalpunkts. Verwenden Sie also den Modul.

Diese Technik kann dann verwendet werden, um die folgenden Dezimalzeichen zu erhalten, z. B. 100 anstelle von 10 usw.


Wenn Sie diese Technik in Echtzeitsystemen verwenden, um sie beispielsweise auf einer 7-Segment-Anzeige anzuzeigen, funktioniert sie möglicherweise nicht ordnungsgemäß, da wir mit einem Float-Wert multiplizieren, bei dem die Multiplikation viel Zeit in Anspruch nimmt.

0
Wilhelm