Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 08.06.2022
Сообщений: 4

Проблема со сравнением double

08.06.2022, 15:31. Показов 1214. Ответов 6

Студворк — интернет-сервис помощи студентам
Всем добрый день!

Выполняю задание №7 к главе 4 книги Страуструпа "Программирование. Принципы и практика...".
Цель задания: вводить единовременно одно число и одну единицу измерения, выводить их на экран и сравнивать их с ранее введенными. Если последнее введенное больше, чем наибольшее ранее введенное, или меньше наименьшего ранее введенного, нужно вывести на экран соответствующую фразу. Имеется 4 допустимых единицы измерения - m, cm, in, ft.
Имею проблему со сравнением значения 0.0254 m / 1 in / 2.54 cm. После первой записи с любой единицей измерения программа повторно выводит сообщение для единицы cm, хотя приведенное значение не менялось.

Вот код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<std_lib_facilities.h>
#include<Windows.h>
 
 
int main()
{
    SetConsoleCP(1251); // Функция SetConsoleCP устанавливает кодовую страницу ввода данных, аргумент 1251 - набор символов для русскоязычной windows. Работает с библиотекой windows.h
    SetConsoleOutputCP(1251); // Функция SetConsoleOutputCP устанавливает кодовую страницу вывода данных, аргумент 1251 - набор символов для русскоязычной windows
 
    string unit; 
    double number;
    double min = 0;
    double max = 0;
    constexpr double cm_to_m_coef = 0.01; // коэффициент см в м
    constexpr double in_to_m_coef = 2.54 / 100; // коэффициент дм в м
    constexpr double ft_to_m_coef = 12 * 2.54 / 100; // коэффициент фут в м
 
    while (cin >> number >> unit) { //вход в цикл ввода цифр и обозначений
        cout << number << unit; // выводим на экран цифры и обозначения
        if (unit == "cm") { // если см
            number *= cm_to_m_coef; // примодим к метрам
        } else if (unit == "in") { // если дюймы
            number *= in_to_m_coef; //приводим к метрам
        } else if (unit == "ft") { // если футы
            number *= ft_to_m_coef; //приводим к метрам
        } else if (unit == "m") { // если метры
            } // ничего не трогаем
 
        cout << " == " << number << " meters" << '\n';
        
        // далее проверяем, не является ли введенное значение больше или меньше ранее введенных самых больших или самых малых
        if (number < min) { // если меньше минимального
            min = number; // меняем минимальное
            cout << "Наименьшее среди введенных" << '\n' << '\n';
        } else if (number > max) { // если больше максимального
            max = number; //меняем максимальное
            cout << "Наибольшее среди введенных" << '\n' << '\n';
            } else {// в ином случае
            cout << '\n';}
 
    }
        
    keep_window_open();
    return 0;
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.06.2022, 15:31
Ответы с готовыми решениями:

Проблема со сравнением в шаблонах
Всем привет. Такая ситуация: template&lt;typename T&gt; class mlist { public: void insert(T data, int position = -1);

Проблема со сравнением в шаблонах
Всем привет. template&lt;typename T&gt; class mlist { public: void insert(T data, int position = -1);

[Error] cannot convert 'double (*)(double)' to 'double' for argument '1' to 'double pow(double, double)'
#include &lt;iostream&gt; #include &lt;math.h&gt; using namespace std; int main () { system(&quot;cls&quot;); double x,y; system (&quot;echo...

6
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,261
08.06.2022, 16:22
Цитата Сообщение от The_beginner Посмотреть сообщение
#include<std_lib_facilities.h>
Что это?

Цитата Сообщение от The_beginner Посмотреть сообщение
После первой записи с любой единицей измерения программа повторно выводит сообщение для единицы cm, хотя приведенное значение не менялось.
1. Ничего не понятно. О каком сообщении идет речь?
2. Не воспроизводится. Все рабоатет, как ожидается
3. Не существует чисел double 0.0254 и 2.54. Результат сравнения будет зависеть от того, какие числа получатся на самом деле.

Цитата Сообщение от The_beginner Посмотреть сообщение
double min = 0;
Это не будет работать правильно с таким начальным значением min, но вы почему-то на это не жаловались.
0
0 / 0 / 0
Регистрация: 08.06.2022
Сообщений: 4
08.06.2022, 18:29  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Что это?
Это заголовок, который автор книги рекомендует использовать как стандартный. Вот он
https://www.stroustrup.com/Pro... cilities.h

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
1. Ничего не понятно. О каком сообщении идет речь?
"Наименьшее среди введенных" или "Наибольшее среди введенных"

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
2. Не воспроизводится. Все рабоатет, как ожидается
При последовательном вводе 0.0254m, 1in, 2.54cm получается результат, как в приложенном скриншоте. Я предполагаю, что в случае 2.54 cm не должно быть возврата строчки "Наибольшее среди введенных", т.к. в этом случае не должно быть number >max.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это не будет работать правильно с таким начальным значением min, но вы почему-то на это не жаловались.
Заменил на 0.0, ничего не поменялось.
Изображения
 
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,261
08.06.2022, 19:21
Цитата Сообщение от The_beginner Посмотреть сообщение
Это заголовок, который автор книги рекомендует использовать как стандартный.
Спорная рекомендация.

Цитата Сообщение от The_beginner Посмотреть сообщение
При последовательном вводе 0.0254m, 1in, 2.54cm получается результат, как в приложенном скриншоте. Я предполагаю, что в случае 2.54 cm не должно быть возврата строчки "Наибольшее среди введенных", т.к. в этом случае не должно быть number >max.
Еще раз: Не существует чисел double 0.0254 и 2.54. Результат сравнения будет зависеть от того, какие числа получатся на самом деле.

В вашем случае второй результат действиельно больше превого. Потому полученное сообщение формально вполне оправданно.

Если вы хотите этого избежать, то в такой ситуации вам придется делать сравнение с допуском.

Цитата Сообщение от The_beginner Посмотреть сообщение
Заменил на 0.0, ничего не поменялось.
И не должно было.
1
0 / 0 / 0
Регистрация: 08.06.2022
Сообщений: 4
08.06.2022, 19:50  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Спорная рекомендация.
В данном случае это не важно. Достаточно того, что обеспечивается работа нужных на данном этапе функций.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Не существует чисел double 0.0254 и 2.54. Результат сравнения будет зависеть от того, какие числа получатся на самом деле.
Поясните, пожалуйста. Я не понимаю, к чему Вы клоните. Мы проверяем значение переменной number. И мы видим это значение когда приводим все к "метрам". После ввода 0.0254m переменная number == 0.0254, и также переменная max == 0.0254. После ввода 2.54cm также number == 0.0254. Почему проходит проверка number > max ?

Цитата Сообщение от The_beginner Посмотреть сообщение
Это не будет работать правильно с таким начальным значением min, но вы почему-то на это не жаловались.
Понял, что имеете в виду. Это я переделаю.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,261
08.06.2022, 20:23
Лучший ответ Сообщение было отмечено The_beginner как решение

Решение

Цитата Сообщение от The_beginner Посмотреть сообщение
Поясните, пожалуйста.
Тип double внутренне представлен в двоичном плавающем формате. В этом формате вообще невозможно представить десятичное число 0.0254. Такого числа не существует в двоичном плавающем формате. Все представимые числа будут имет дробную часть оканчивающуюся на 5. Если дробная часть не оканчивается на 5, то число - непредставимо.

Цитата Сообщение от The_beginner Посмотреть сообщение
И мы видим это значение когда приводим все к "метрам". После ввода 0.0254m переменная number == 0.0254, и также переменная max == 0.0254.
Нет, эти переменные имеют другие значения, отличные от 0.0254. Это на экране вы видите некое 0.0254, потому что вывод на экран вы осуществляете с огрублением/округлением.

Попросите std::cout выводить данные на экране с более высокой точностью (используя std::setprecision) и вы увидите, что там совсем не 0.0254. Заодно вы увидите, что ваша программа ведет себя формально корректно - там действительно достигается новый максимум.
1
0 / 0 / 0
Регистрация: 08.06.2022
Сообщений: 4
08.06.2022, 20:32  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Попросите std::cout выводиь данные на экране с более высокой точностю (используя std::setprecision) и вы увидите, что там совсем не 0.0254
Теперь понял. Спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.06.2022, 20:32
Помогаю со студенческими работами здесь

Ошибки error C2296: -: недопустимо, левый операнд имеет тип "double (__cdecl *)(double,double,double
Думаю из-за polp #include&lt;iostream&gt; #include&lt;cmath&gt; #include&lt;cstdlib&gt; using namespace std; double polp(double af,double...

Ошибка: error LNK2001: unresolved external symbol "double __cdecl Akk(double,double,double)"
#include &lt;iostream&gt; #include &lt;cmath&gt; using namespace std; double Akk(double x, double y, double z); int main() { int a, b, c; ...

Проблема с long double
Имеется приблизительно такой код long double f13(double **k, long double x5, long double x6, long double x3, long double x13) { ...

Проблема со сравнением значений(символов) в переменных типа AnsiString
Здравствуйте! Почему то при сравнении двух одинаковых символов в переменных str и b(тип AnsiString), билдер игнорирует совпадения....

Проблема со сравнением файлов
Доброго времени дня!Пожалуйста помогите в написании программы=)Нужно ввести 2 пути файла с консоли и найти сколько раз содержание второго...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru