While循环的Printf问题

时间:2011-08-18 08:13:50

标签: c

我在C中创建一个温度转换器。基本上,您输入一个以摄氏度为单位的最小值和最大值,以及一个步骤,它会在列表中显示该信息以及华氏温度等效值。在某些情况下,我注意到最后的华氏温度条目没有显示。例如,当您输入下限10,上限30和步长4时,它会切断最后的华氏温度。我知道这与最后一个while循环有关,但我无法理解它。

#include <stdio.h>

int main (int argc, const char * argv[]) {
double l, h, s;
double lf, hf, sf;
/* Number rows in tables */
int num1, num2;
num1 = 1;
num2 = 1;

/* Lower limit input */
printf("Please give a lower limit: ");
scanf("%4lf", &l);
while (l < 0) {
        printf("Lower limit must be greater than 0: ");
        scanf("%4lf", &l);
}

/* Stores value for Fahrenheit conversion */
lf = l;

/* Higher limit input */
printf("Please give a higher limit: ");
scanf("%4lf", &h);
while (h <= l) {
        printf("Higher limit must be greater than lower limit: ");
        scanf("%4lf", &h);
}

while (h >= 50000) {
        printf("Higher limit must be less than 50000: ");
        scanf("%4lf", &h);
}

hf = h;

/* Step input */
printf("Please input step: ");
scanf("%4lf", &s);
while (s <= 0) {
        printf("Step must be greater than 0: ");
        scanf("%4lf", &s);
}

while (s >= h - l) {
        printf("Step must be less than the difference in temperatures: ");
        scanf("%4lf", &s);
}

sf = s;

/* Celsius table */
printf("\nCelsius\n-------\n");
while (l <= h) {
    printf("%i. %4lf\n", num1, l);
    num1++;
    l = l + s;
}

/* Fahrenheit table */
printf("\nFahrenheit\n----------\n");
/* Converts Celsius to Fahrenheit */
lf = (lf * 1.8) + 32;
hf = (hf * 1.8) + 32;
sf = sf * 1.8;
printf("Lower input: %4lf\n", lf);
printf("Higher input: %4lf\n", hf);
printf("Step: %4lf\n----------\n", sf);
/* This while loop sometimes cuts off the last entry */
while (lf <= hf) {
    printf("%i. %4lf\n", num2, lf);
    num2++;
    lf = lf + sf;
}

return 0;

}

4 个答案:

答案 0 :(得分:3)

问题在于比较双打,你可能会遇到类似10 + 1.8的问题评估为11.800000001并因此错过最终值的情况。

问题的解决方案是首先计算步数:

int steps = (h - l) / s + 1; //Might want to apply rounding

然后在整数变量上使用for/while循环:

for (int i = 0; i < steps; ++i) {
    double t = l + (h - l) * i / (steps - 1);
}

for (int i = 0; i < steps; ++i) {
    double tf = lf + (hf - lf) * i / (steps - 1);
}

答案 1 :(得分:2)

while (lf <= hf) 

您正在比较Double值,您将遇到 Precison &amp; 舍入错误,很可能导致最后一次迭代根本不执行。

This 我的答案应该是一个很好的阅读。

答案 2 :(得分:0)

选择一个精度并将其与hf和lf(绝对值)之间的差值进行比较。 另外,请记住随机固定步骤,您不会总是达到间隔的最高值。如果步骤除了h-l,它可能会起作用但是否则不起作用。

答案 3 :(得分:0)

在你的最后一个while循环之后,添加以下代码(不要忘记#include assert.h):

printf("lf = %f, hf = %f\n", lf, hf);
assert(lf == hf);

你应该得到这个输出:

Celsius
-------
1. 10.000000
2. 14.000000
3. 18.000000
4. 22.000000
5. 26.000000
6. 30.000000

Fahrenheit
----------
Lower input: 50.000000
Higher input: 86.000000
Step: 7.200000
----------
1. 50.000000
2. 57.200000
3. 64.400000
4. 71.600000
5. 78.800000
lf = 86.000000, hf = 86.000000
Assertion failed: lf == hf, file randomdudescode.c, line 77

这令人难以置信的混乱,因为很明显lf == hf。 这说明了C和浮点嗡嗡声的一个怪癖。你必须处理舍入错误和不精确。