10
votes

Comment convertir une valeur flottante en entier avec une précision exacte comme 123,3443 à 1233443?

code d'exemple: xxx


4 commentaires

Et si le numéro est 1.99999999999999 / code>? Astuce: Qu'est-ce que vous essayez de faire n'est pas possible. (ou au moins il est mal défini avec un point flottant binaire)


Peut-être que ce que vous voulez, c'est d'obtenir autant de flotteur à gauche d'une partie proche de zéro (avec une certaine tolérance)?


@ Mysticial: C'est toujours toujours possible avec un point flottant, car l'exposant FP est une puissance de 2. Les résultats ne seront généralement pas ce que vous voulez (par exemple, cela ne fonctionnera que pour les fractions binaires exactes).


En supposant un flotteur IEEE 32 bits, la valeur décimale exacte de F dans votre exemple sera 123.54199981689453125. Ce n'est pas ce qui serait imprimé par Printf, car il utilise une heuristique qui imprime la représentation la plus courte qui, si elle est dosée à flotter, vous donnerait exactement le même flotteur. Je mentionne ceci pour souligner que d'autres sont exactes que votre question pourrait ne pas être assez bien formée pour fournir une bonne réponse.


6 Réponses :


2
votes
int i = (int) (f * 10000 + 0.5);

1 commentaires

Pas vraiment de réponse généralement utile (bien que l'orchestre obtiendrait exactement ce qu'il a demandé). C'est (très) probablement pas ce qu'il avait à l'esprit.



0
votes

multiplier le float par 10 ^ x x est le nombre de chiffres après la décimale que vous voulez, puis jeté sur int .


1 commentaires

Cela fonctionnera, mais vous assume que vous connaissez le nombre de décimales que vous souhaitez à l'avance.



10
votes

123.3443 ne peut pas être exactement représenté par un numéro de point flottant - dans un flotteur 32 bits, il est efficacement représenté comme 16166984/131072 , qui est en fait 123,34429931640625, pas 123.3443. (Il est désactivé d'environ 6,8 x 10 ^ -7.)

Si c'est vraiment le résultat que vous voulez (ce qu'il n'est probablement pas), examinez comment ICEE-754 flotte et sortez votre suite de mathématiques arbitraires préférées. Une fois que vous comprenez ce qui se passe "dans les coulisses", générer une représentation exacte ne devrait pas être trop dur. Générer une représentation arrondie «assez proche» est effectivement beaucoup plus difficile. :)


0 commentaires

-1
votes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int f2i(float v, int size, int fsize){
    char *buff, *p;
    int ret;
    buff = malloc(sizeof(char)*(size + 2));
    sprintf(buff, "%*.*f", size, fsize, v);
    p = strchr(buff, '.');
    while(*p=*(p+1))p++;
    ret = atoi(buff);
    free(buff);
    return ret;
}

int main(){
    float f = 123.3443;

    printf("%d\n", f2i(f, 7, 4));

    f=123.542;
    printf("%d\n", f2i(f, 6, 3));
    return 0;
}

0 commentaires

0
votes

Si vous n'avez pas besoin de traiter un traitement répétitif du nombre converti et que vous souhaitez convertir uniquement les chiffres en un entier, le moyen le plus simple consiste à utiliser Sprintf, puis résumez les décimales avec une boucle pour la puissance de la puissance de 10 règles. Si vous avez besoin de «précision exacte» pour les mathématiques, utilisez un BCD. L'algorithme suivant vous permettra de tronquer le nombre de chiffres pour "précision exacte".

#include "math.h"

long ConvertToScaledInteger (float value, int significantDigits = -1)
{
    // Note: for 32-bit float, use long return and for double use long long.

    if (significantDigits < 1)   // Ditch the '-' and the '.'
        significantDigits += 2;
    else
        ++significantDigits;     // Ditch the '.'

    char* floatingPointString = malloc(sizeof (char) * (4 + FLT_MANT_DIG - FLT_MIN_EXP));
    /*< This solution  is for a 32-bit floating point number. Replace FLT 
         with DBL, and it will produce the max number of chars in a 64-bit 
         float string. */

    if (significantDigits < 0)   //< Then use all of the float's digits.
    {
        sprintf (floatingPointString , "%f", floatingPointNumber);
    }
    else    //< Then truncate the number of decimal places.
    {
        char decimalPlaceString[9];
        char percentString = "%\0";
        sprintf (decimalPlaceString, "%s%if", percentString , significantDigits);
        sprintf (floatingPointString , decimalPlaceString, value);
    }

    int stringLength = strlen (floatingPointString),
        index;
    long returnValue = 0;
    double powerOfTen = 10.0,
        currentValue;

    // Find if we have an ending of .0, and backtrack.
    if (floatingPointString[stringLength - 1] == '0' && floatingPointString[stringLength - 2] == '.')
        index = stringLength - 3;
    else
        index = stringLength - 1;

    for (; index > 0; --index)
    {
        if (floatingPointString[index] == '.')
            --index;

        // Subtract ASCII '0' converts ASCII to integer.

        currentValue = (double) floatingPointString[index] - '0';
        returnValue += (long) currentValue * pow (10.0, powerOfTen);

        powerOfTen += 1.0;
    }

    if (floatingPointString[0] == '-')
        returnValue *= -1;

    return returnValue;
}


5 commentaires

Pourquoi répondre avec C ++ Code pour un poste C? Recommander le portage à C.


4 + flt_mant_dig - flt_min_exp est trop petit. Voir Commentaire


"\ %% si" séquence d'échappement non valide.


1) avec int index; ... Si (FloatingPointString [Index - 1] , l'index n'est pas initialisé. 2) L'algorithme a une certaine promesse, mais est nécessaire à de nombreuses erreurs. Suggérez une critique, un test et une ré-post.


Je vois ce que tu disais. J'ai corrigé les erreurs mais le code n'est pas débogué. La taille maximale de la chaîne est correcte. Ceci est pour un flotteur 32 bits. Remplacez la FLT avec DBL et flotter au double et il fonctionnera correctement. Voir la piste de pile suivante POST pour la taille maximale de flotteur: Stackoverflow.com/questions/1701055/...



0
votes

L'équivalent entier d'un float code> numéro f code> xxx pré>

peut être effectué en utilisant modff () code> comme p> xxx pré> maintenant intégrale code> a la partie entière (comme 123.000000) et fractional code> a la partie fractionnée (comme 0,456000). P>

si le nombre de points flottants ( f code> dans ce cas) était négatif, les deux intégrale code> et fractional code> serait négatif. p>

vous pouvez faire p >

long l=strtol(str, NULL, 10);
if(l>INT_MAX || errno==ERANGE)
{
    printf("\noverflow");
}
else
{
    printf("\n%d", strtol(str, NULL, 10));
}


0 commentaires