浮点到字符串转换时出错

时间:2014-03-25 14:03:18

标签: java c++ c floating-point-precision

给定一个浮点数7.64,使用任何内置函数/库将其转换为字符串WITHOUT。 这个问题在java中很容易。由于+运算符为字符串重载。我们可以做

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

但在c中,我尝试这样做..

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

这里的问题是浮点错误开始潜入,而循环进行,j留下不正确的小数部分。 例如,在上面的情况下,f的值变化如 123

那么如何在c或C ++中解决这个问题。

3 个答案:

答案 0 :(得分:1)

解决方案是使用float支持的精度(=位数)打印f。

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

答案 1 :(得分:1)

突然跳转到完全错误的值是由j溢出其int引起的。您可以使用unsigned long

Thel循环可能不会达到0但是,由于事实,浮点数只是2的(负)幂之和的近似值。当乘以10然后减去整数时,这些和不会减少一部分。

最好的方法是使用固定的位数,乘以10 n 然后砍掉尾随的零。

答案 2 :(得分:0)

除了指定小数位数之外,考虑浮点不准确性的另一种计算小数值的方法是使用FLT_EPSILON中定义的DBL_EPSILON(或float.h)。

FLT_EPSILON是1.0与大于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;
    }