Domanda

Given a float number 7.64, convert it into the string WITHOUT using any inbuilt function/library. This problem is easy in java . As + operator is overloaded for strings .We can do

class Float2String 
{ 
    public static void main(String[] args) 
    { 
        float f=7.64f; 
        String result; 
        result=""+f; 
        System.out.println(result); 
    } 
}

But in c as i try to do so ..

int main()
{
    float f =2.44;
    int i, j = 0;
    i = (int) f;

    f = f - i;
    while(f > 0) {
        f *= 10;
        j = (j*10) + (int) f;
        f = f - (int) f;
    }
    //now make itoa() to convert i and j to strings .      
    return 0;
}

Here problem is that floating point error begin to sneak into as while loop goes and j is left with incorrect decimal part . for example in above case value of f varies like 123

So how to do this problem in c or C++ .

È stato utile?

Soluzione

The sudden jump to an entirely wrong value is caused by j overflowing its int. You could use an unsigned long.

Thel loop will probably not reach 0 however, due to the fact, that floating point numbers are just an approximations of a sum of (negative) powers of 2. Such sums will not decrease when multiplying by 10 and then subtracting the integer part.

The best way would be having a fixed number of digits, multiplying with 10n and then chopping trailing zeroes.

Altri suggerimenti

The solution is to print f with the precision (=number of digits) supported by float.

int main()
{
    float f =2.44;
    int i, len;
    char str[100];

    i = (int) f;
    itoa(i, str, 10);
    len = strlen(str);
    str[len] = '.'; 

    f = f - i;
    while(len <= 6) {
        len++;
        f *= 10;
        str[len] = '0' + (int)f;
        f = f - (int) f;
    }
    str[len + 1] = '\0';

    /* Remove trailing zeroes and decimal points. */
    for (;len > 0 && (str[len] == '0' || str[len] == '.'); --len) {
        if (str[len] == '.') {
            str[len] = '\0';
            break;
        }
        str[len] = '\0';
    }
    printf("%s", str);
    return 0;
}

Apart from specifying the number of decimal places, the other way to calculate the decimal value taking into account floating point inaccuracies is to use FLT_EPSILON (or DBL_EPSILON) defined in float.h.

FLT_EPSILON is the difference between 1.0 and the minimum float value greater than 1.0

  #include<stdio.h>
  #include<float.h> 
  int main()
    {
        float origf = 2.44;
        float f = origf, newf = 0.0;
        int i, j = 0;
        int powerOfTen = 1;
        i = (int) f;
        f = f - i;
        do
        {
            f *= 10;
            powerOfTen *= 10;
            j = j * 10 + (int)f;
            f = f - (int) f;

            newf = i + (float)j/ powerOfTen;
        } while ((origf + FLT_EPSILON) > newf && newf > (origf - FLT_EPSILON)); 
        printf("%d %d\n", i, j);
        return 0;
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top