ДТ
Даниил Тетерин23 декабря 2018 г. 23:33

Простой калькулятор

На самом деле, задание действительно простое. Проблема есть лишь в выводе результата.

            double result;
            if(ui->radioButton_s->isChecked())
            {
                result=oper1+oper2;
                if (result>=qInf() or result<=-qInf())
                    ui->label_res->setText("Близость к бесконечности - ошибка");
                else
                    ui->label_res->setText(tr("%1").arg(result));

Участок кода, где результат выводиться в QLabel. Оба оператора, естественно, тоже double. Так вот, если при таком раскладе попытаться сложить слишком маленькие числа, то оно попросту начнет их округлять:

Если же чуть изменить метод вывода на

ui->label_res->setText(QString::number(result,'g',39));

, то результат перестанет округляться, но начнет появляться непонятный "мусор".

Что это за "мусор", почему он появляется, и как, в таком случае, нормально выводить ответ?

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

5
ДТ
  • 24 декабря 2018 г. 0:05

Через некоторое время я осознал, что проблема не столько в выводе, сколько при самом переводе из текста в число. Почему одно число, что было без плавающей точки, перевелось нормально, а второе так ужасно? Почему так происходит?

    Evgenii Legotckoi
    • 24 декабря 2018 г. 1:12
    • (ред.)

    Добрый день!

    Потому, что все компьютеры имеют ограничения по количеству разрядов для чисел с плавающей запятой. И всегда точность будет ограничена разрядностью.

    Существуют специальные библиотеки для проведения расчётов с числами, для которых требуется большая точность, чем позволяет разрядность ПК.

    Но в вашем случае не имеет смысла использовать подобную библиотеку, вы же не научные изыскания ведёте.

    В общем смиритесь, в определённых ситуациях всегда будет некоторое округления. Это особенность архитектуры ПК и ограничений с количество разрядов для каждой конкретной архитектуры. Единственное решение - это задавать разрядность для округления.

      ДТ
      • 24 декабря 2018 г. 2:39
      • (ред.)

      Извиняюсь, но это даже не округление, это ерунда какая-то. Почему при переводе строки "0.344" через .toDouble(), оно в итоге получает число 0.343999999999...? В смысле, ладно, хорошо, я смирился. Но когда преподаватель спросит "А почему КОНКРЕТНО так происходит?", что мне ему ответить?

        Evgenii Legotckoi
        • 24 декабря 2018 г. 2:53

        Нет никакой ерунды, просто архитектура компьютера не позволяет корректно хранить число с плавающей запятой 0.344

        Это дробь, а дроби имеют свойство быть бесконечными в плане разрядности. Компьютер просто не может корректно представить это число.

        Просто есть числа, чтобы корректно хранить которые требуется больше чем 64 разряда. Дроби как раз часто и относятся к таким числам.

        Почитайте про числа с плавающей точкой, мантиссу числа и т.д. а также про разрядность компьютеров и т.д. И попробуйте написать в двоичном виде число 0.344, сами увидите, что разрядов вам не хватит, поэтому и получите что-то вроде 0.343999999999..

          Evgenii Legotckoi
          • 24 декабря 2018 г. 3:08
          • (ред.)

          Я сам уже не помню, как правильно представлять дроби в двоичном представлении (давно этим не занимался в силу отсутствия необходимости), но по факту проблема в том, что двоичное представление ограничено количеством разрядов, а некоторые дроби для своего представления требуют больше разрядов, чем есть в распоряжении ПК, вот и выскакивают такие глюки. Это погрешность из разряда нормы. Если хотите более полного объяснения, то Вам потребуется прочитать про формирование числа с плавающей точкой и попытаться вручную, на листе, например, попытаться написать 0.344 в двоичном виде, например, для ограничения в 32 разряда. Когда разряды закончатся, то попытайтесь привести это число в десятичный вид, получите 0.343999999999..

            Комментарии

            Только авторизованные пользователи могут публиковать комментарии.
            Пожалуйста, авторизуйтесь или зарегистрируйтесь
            Ua

            Qt - Тест 001. Сигналы и слоты

            • Результат:84баллов,
            • Очки рейтинга4
            Ua

            Qt - Тест 001. Сигналы и слоты

            • Результат:42баллов,
            • Очки рейтинга-8
            ОК

            Qt - Тест 001. Сигналы и слоты

            • Результат:47баллов,
            • Очки рейтинга-6
            Последние комментарии
            ИМ
            Игорь Максимов22 ноября 2024 г. 21:51
            Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
            Evgenii Legotckoi
            Evgenii Legotckoi31 октября 2024 г. 23:37
            Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
            A
            ALO1ZE19 октября 2024 г. 17:19
            Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
            ИМ
            Игорь Максимов5 октября 2024 г. 16:51
            Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
            d
            dblas55 июля 2024 г. 20:02
            QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
            Сейчас обсуждают на форуме
            f
            firstlunoxod15 февраля 2025 г. 13:46
            Рисование на QGraphicsScene при зажатой кнопке мыши Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
            Дмитрий
            Дмитрий3 февраля 2025 г. 16:24
            Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
            NW
            Nayo Wai30 января 2025 г. 19:22
            не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
            n
            nkly3 января 2025 г. 12:52
            Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
            M
            Marsel17 августа 2023 г. 0:26
            OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

            Следите за нами в социальных сетях