博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助
在我的系统上成功不代表在你的系统上也成功。请按自己的需要进行修改。 1. /usr/share/doc下一定要看 2. 更详细的可以看看man, 看man 的时间远小于上网找答案的时间
  cobalt65.cublog.cn

关于作者
Debian stable
Email:angelerosster@gmail.com
|| << >> ||
我的分类


C中数值计算自动取整的问题及解决方法

#include <stdio.h>

int main()
{
    float fahr,celsius;
    int lower,upper,step;
    lower = 0;
    upper = 300;
    step = 20;
    fahr = lower;
    while (fahr <= upper) {
        celsius = 5 / 9 * (fahr-32);
        printf("wrong:%3.0f\t%6.1f\n",fahr,celsius);
        fahr = fahr + step;
    }
    return 0;
}



#include <stdio.h>

int main()
{
        float fahr,celsius;
        int lower,upper,step;
        lower = 0;
        upper = 300;
        step = 20;
        fahr = lower;
        while (fahr <= upper) {
                celsius = 5 * (fahr-32) / 9;
                printf("correct:\t%3.0f\t%6.1f\n",fahr,celsius);
                fahr = fahr + step;
        }
        return 0;
}


这两个程序看上去差不多,就是其中一行表达式的写法上有点差异,理论上应该是一样的输出,但其实不同。
第一个输出的 celsius 全是 0,而第二个能得到正确的答案。

原因在于 C 语言对于 5/9,这样的表达式,会把当成是两个整数相除,因此 C 自动对这一步的结果取整,最后的输出也就会全 0 了。根据 K&R 的说话,不仅仅是 C 语言这样处理的,还有很多语言也是这样的。

所以最好的程序写法应该是人为地用 5.0/9.0,强迫它认为是两个浮点数相除。在 fahr-32 这一表达式中,C 语言会对 32 自动进行整型数到浮点数的转换。所以好习惯就是写成 fahr-32.0,提醒自己这个 fahr 是 float 型变量。还有一个技巧也可以绕过这个问题,把 celsius = 5 / 9 * (fahr-32),像第二个例子那样写成 celsius = 5 * (fahr-32) / 9这其实是利用了 C 语言的强制类型转换。

综上,最好的写法如下:

#include <stdio.h>

int main()
{
        float fahr,celsius;
        int lower,upper,step;
        lower = 0;
        upper = 300;
        step = 20;
        fahr = lower;
        while (fahr <= upper) {
                celsius = 5.0 * (fahr-32.0) / 9.0;
                printf("%3.0f\t%6.1f\n",fahr,celsius);
                fahr = fahr + step;
        }
        return 0;
}

发表于: 2007-12-19,修改于: 2007-12-19 18:15,已浏览242次,有评论0条 推荐 投诉


网友评论
 发表评论