2009-02-01 10 views
38

Comment peut-on extraire la partie décimale d'un nombre à virgule flottante et de stocker la partie décimale et la partie entière en deux variables entières séparées?Extrait de partie décimale d'un nombre à virgule flottante en C

+0

Comment/pourquoi voulez-vous représenter la partie décimale dans un nombre entier? –

+5

Comment distingueriez-vous les fractions décimales dans 1.5 et 1.005? – SingleNegationElimination

+0

Je ne vois pas comment vous pourriez mettre la partie décimale dans un entier sauf si vous saviez combien de chiffres vous voulez garder. Pourriez-vous donner quelques exemples? – Nosredna

Répondre

76

Vous utilisez la fonction modf:

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

Vous pouvez également jeter un entier, mais attention, vous pouvez déborder l'entier. Le résultat n'est pas prévisible alors.

+1

http://codepad.org/A0ilp9eE Cela ne semble pas fonctionner – penu

+1

@penu C'est parce que vous utilisez '% d' pour imprimer' double'. Voici le code de travail: http://codepad.org/kPGKtcZi –

38

Essayez ceci:

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); 
} 

Pour moi, il produit:

Num = 23.345000, intpart = 23, decpart = 0.345000 

qui semble être ce que vous demandez.

+1

la première partie est correcte mais souhaite obtenir le résultat en tant que partie décimale en tant que 345000 entier – Binu

+1

mais je veux obtenir la partie deciaml en tant que valeur entière qui signifie démissionner = 345000 – Binu

+1

int decpart = 100000 * (num - intpart); – SingleNegationElimination

1

I créé un sous-programme à l'aide d'une double flotteur, il renvoie 2 valeurs entières.


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); 
    } 
} 
 
12

Le rapide « dans une coquille de noix » réponse la plus évidente semble être:

#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); 

Vous changerais le nombre de décimales que vous voulez en changeant la N_DECIMAL_POINTS_PRECISION en fonction de vos besoins.

+1

Juste pour le plaisir. Faisons une réflexion experiement: La solution la plus obscure et la plus complexe (voir "difficile à maintenir le code") pourrait aller aussi loin que [bit slicing] [1] le float ou double pour obtenir les réels ["integerBits" et "fractionalBits "] [2]. –

+0

Je ne suis pas exactement sûr de savoir pourquoi vous feriez cela ...peut-être que cette méthode aurait l'avantage de capturer les parties entières et décimales directement sans perdre la précision due à l'arrondi en virgule flottante. –

+0

Voici un code pseudo incomplet pour vous donner l'idée: #define BIT_MASK1/* pas sûr */define SHIFT/* pas sûr */define BIT_MASK2/* pas sûr */ flotteur f = 123,456 ; uint32_t * tmp = (uint32_t *) & f; int nombre entierPart = (int) f; –

-1

Peut-être la meilleure idée est de résoudre le problème alors que les données sont au format chaîne. Si vous avez les données sous forme de chaîne, vous pouvez l'analyser en fonction du point décimal. Vous extrayez la partie intégrale et décimale en sous-chaînes, puis convertissez ces sous-chaînes en entiers réels.

+0

La convertir en une chaîne juste pour cela est un peu bête, mais si c'était une ficelle à l'origine alors c'est logique. –

+0

Comme mentionné ci-dessus considèrent 1.5 et 1.005 ... – Mikhail

-1

J'ai fait cette fonction, il semble bien fonctionner:

#include <math.h> 

void GetFloattoInt (double fnum, long precision, long *pe, long *pd) 
{ 
    long pe_sign; 
    long intpart; 
    float decpart; 

    if(fnum>=0) 
    { 
    pe_sign=1; 
    } 
    else 
    { 
    pe_sign=-1; 
    } 

    intpart=(long)fnum; 
    decpart=fnum-intpart; 

    *pe=intpart; 
    *pd=(((long)(decpart*pe_sign*pow(10,precision)))%(long)pow(10,precision)); 
} 
0

Voici une autre façon:

#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

Sortie:

whole: 123 
mantissa: 4567 
+0

Votre code ne fonctionnera pas sur les plates-formes 16 bits où les longs sont 32 bits et long double sont 53 bits. – user2284570

3

Je pense que l'utilisation string est la bonne façon de procéder dans ce cas, puisque vous ne connaissez pas a priori le nombre de chiffres dans la partie décimale. Mais, cela ne fonctionnera pas dans tous les cas (par exemple, 1.005), comme mentionné précédemment par @SingleNegationElimination. Voici mon avis sur ceci:

#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; 
} 
0

Si vous voulez juste pour obtenir la première valeur décimale, la solution est très simple.

Voici un exemple explicatif:

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

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

Dites par exemple, nous avons une valeur flottante initiale de 27,8. En convertissant simplement la valeur initiale du flottant en entier, vous supprimez la partie fraction et ne gardez que la partie entière.En multipliant la valeur flottante initiale par 10, nous obtenons un résultat de 278,0, puis en donnant ce résultat à int, vous donne la valeur de 278

  • Si nous divisons 278 par 10, nous obtenons 27,8, dont le reste est 8, qui est la valeur à droite du point décimal. Utilisez donc le module. Cette technique peut ensuite être utilisée pour obtenir les caractères décimaux suivants en utilisant, par exemple, 100 au lieu de 10, et ainsi de suite.


    Il suffit de prendre note que si vous utilisez cette technique sur les systèmes en temps réel, par exemple pour l'afficher sur un afficheur 7 segments, il ne fonctionne pas correctement parce que nous multiplions avec une valeur flottante, où la multiplication prend beaucoup de temps.

  • -1
    cout<<"enter a decimal number\n"; 
    cin>>str; 
    for(i=0;i<str.size();i++) 
    { 
        if(str[i]=='.') 
        break; 
    } 
    
    for(j=i+1;j<str.size();j++) 
    { 
        cout<<str[j]; 
    } 
    
    +1

    Pourriez-vous ajouter des commentaires à votre réponse? – kvorobiev

    +0

    Bien que cet extrait de code puisse résoudre la question, [y compris une explication] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) aide vraiment à améliorer la qualité de votre message. Rappelez-vous que vous répondez à la question pour les lecteurs dans le futur, et que ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. –

    0

    Même je pensais comment le faire. Mais j'ai trouvé un moyen. Essayez ce code

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

    Sortie: -

    Enter a floating number 
    23.13 
    Number=23 Decimal part=13 
    
    Questions connexes