简体   繁体   English

While循环的Printf问题

[英]Printf Problem with While Loop

I'm creating a temperature converter in C. Basically, you input a minimum and maximum value in degrees Celsius, along with a step, and it displays that information in a list, along with the Fahrenheit equivalent. 我正在用C创建一个温度转换器。基本上,您输入的最小和最大值为摄氏度,以及一个步长,它将在列表中显示该信息以及华氏温度。 On some occasions, I have noticed the last Fahrenheit entry not being displayed when it should. 在某些情况下,我注意到上一个华氏温度条目在适当的时候没有显示。 For example, when you input a lower limit of 10, a higher limit of 30, and a step of 4, it cuts off the last Fahrenheit temperature. 例如,当您输入下限10,上限30和步长4时,它将切断最后的华氏温度。 I know it's something to do with the last while loop, but I just can't figure it out. 我知道这与上一个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;

}

The problem is with comparing the doubles, you might get into a situation where something like 10 + 1.8 evaluates to 11.800000001 and thus missing the end value. 问题在于比较双打,您可能​​会遇到这样的情况,例如10 + 1.811.800000001 ,因此缺少最终值。

The solution to your problem would be to first calculate the number of steps: 解决您的问题的方法是先计算步骤数:

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

And then use a for/while loop over the integer variable instead: 然后在整数变量上使用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);
}
while (lf <= hf) 

You are comparing Double values, You will face problems of Precison & Rounding Errors , Most likely that causes the last iteration to not execute at all. 您在比较Double值时,将遇到“ 精确度舍入错误”的问题 ,最有可能导致最后一次迭代根本不执行。

This answer of mine, should be a good read. 我的这个答案应该很好读。

Choose a precision and compare it with the difference between hf and lf(abs value). 选择一个精度,并将其与hf和lf(绝对值)之间的差异进行比较。 Also keep in mind with a random fixed step you will not always reach the top value of the interval. 另外请记住,随机的固定步骤将不会总是达到间隔的最大值。 it might work if step divides hl but it won't work otherwise. 如果step除hl可能会起作用,否则就不会起作用。

Directly after your last while loop, add the following code (and don't forget to #include assert.h): 在您的上一个while循环之后,直接添加以下代码(并且不要忘记#include assert.h):

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

you should get this output: 您应该得到以下输出:

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

Which is incredibly confusing, because obviously lf == hf. 这令人难以置信,因为lf == hf。 This illustrates one of the quirks of C and floating point tomfoolery in general. 这通常说明了C和浮点tomfoolery的怪癖之一。 You have to deal with rounding errors and imprecision. 您必须处理舍入错误和不精确性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM