在 c 中四舍五入小数错误?

Rounding up decimals bug in c?

我正在做一个非常简单的 C 程序,它接收整数 n 并找到 n 的平方根近似值。

这是我的平方根近似函数,直到小数点后第 5 位:

float sqrt_approx(int n){
    float sqrt,how_many_tenths=10,how_many_decimals=0,i;
    for (i=1;i<n;i++){
        if ((i*i)<n) continue;
        if (i*i==n){ sqrt=i; goto return_; }
        else break;
    }
    sqrt=i-1;
    for (i=0;i<10;i++){
        if (i==9){

            sqrt=sqrt+i/how_many_tenths;

            how_many_tenths*=10;
            how_many_decimals++;
            if (how_many_decimals != 5) i=0;
            else break;
        }
        if ((sqrt+i/how_many_tenths)*(sqrt+i/how_many_tenths) < n) continue;
        sqrt=sqrt+(i-1)/how_many_tenths;
        how_many_tenths*=10;
        how_many_decimals++;
        if (how_many_decimals != 5) i=0;
        else break;
    }
    return_:
        return sqrt;
}

蛮力,我会说非常直观。然而,当我试图获得小数点后 6 位的近似值时,问题就出现了。为了做到这一点,我需要做的就是改变这个:

if (how_many_decimals != 5)

进入:

if (how_many_decimals != 6)

两次都在我的代码中。如果我要计算 $35$ 的平方根近似值直到小数点后 6 位, 我得到 5.916080 美元而不是 5.916079 美元。

我试图找出错误,在我看来小数点后第 5 位四舍五入。看一下,我只更改了一点代码以了解这里发生了什么:

float sqrt_approx(int n){
    float sqrt,how_many_tenths=10,how_many_decimals=0,i;
    for (i=1;i<n;i++){
        if ((i*i)<n) continue;
        if (i*i==n){ sqrt=i; goto return_; }
        else break;
    }
    sqrt=i-1;
    for (i=0;i<10;i++){
        if (i==9){
            printf("%f + %f equals: ",sqrt,i/how_many_tenths); //NEW
            sqrt=sqrt+i/how_many_tenths; //NEW
            printf("%f\n",sqrt); //NEW
            how_many_tenths*=10;
            how_many_decimals++;
            if (how_many_decimals != 6) i=0; //NEW (6 instead of 5)
            else break;
        }
        if ((sqrt+i/how_many_tenths)*(sqrt+i/how_many_tenths) < n) continue;
        sqrt=sqrt+(i-1)/how_many_tenths;
        how_many_tenths*=10;
        how_many_decimals++;
        if (how_many_decimals != 6) i=0; //NEW (6 instead of 5)
        else break;
    }
    return_:
        return sqrt;
}

结果(输入 printf("%f,sqrt_approx(35) 后):

5.000000 美元 + 0.900000 美元等于:5.900000 美元(很好)

$5.916070+0.000009$ 等于:$5.​​916080$(不合适)

$5.916080$

这里似乎有什么问题?

将 float 更改为 double 修复了它。谢谢大家的评论。