Проблема Printf с циклом while - PullRequest
       0

Проблема Printf с циклом while

0 голосов
/ 18 августа 2011

Я создаю преобразователь температуры в 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 ]

3 голосов
/ 18 августа 2011

Проблема со сравнением двойных чисел, вы можете оказаться в ситуации, когда что-то вроде 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);
}
2 голосов
/ 18 августа 2011
while (lf <= hf) 

Вы сравниваете значения Double, вы столкнетесь с проблемами Precison & Ошибки округления , скорее всего, из-за чего последняя итерация вообще не будет выполняться.

Этот мой ответ должен быть хорошим прочитанным.

0 голосов
/ 18 августа 2011

Сразу после вашего последнего цикла 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 и дурачества в целом.Вам приходится иметь дело с ошибками округления и неточностями.

0 голосов
/ 18 августа 2011

Выберите точность и сравните ее с разницей между hf и lf (значение абс). Также имейте в виду, что при случайном фиксированном шаге вы не всегда достигнете верхнего значения интервала. это может сработать, если шаг делит h-l, но иначе не сработает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...