Форум программистов, компьютерный форум, киберфорум
EvgeniyT
Войти
Регистрация
Восстановить пароль

Сравнение чисел с плавающей точкой

Запись от EvgeniyT размещена 10.01.2019 в 20:41
Показов 3230 Комментарии 3

Нашёл интересную информацию и что бы не потерять выложу сюда. Читайте как справочник.

Типы данных double и float хранят приближённое значение числа, на столько, на сколько хватает их точности. Поэтому нужно быть аккуратным при сравнении таких чисел на равенство.

Рассмотрим такой код:
C#
1
2
3
4
5
6
7
8
9
10
11
1public static void WrongMain()
2{
3    // в бинарном виде 0.1 представляется бесконечной дробью 0.00011001100...,
4    // в типах данных float и double хранится только начало этой дроби,
5    // поэтому число 0.1 представляется с погрешностью. 
6    double x = 1.0 / 10; 
7    double sum = 0;
8    for (int i = 0; i < 10; i++)
9        sum += x;
10    Console.WriteLine(sum == 1);
11}
Кажется, что он должен вывести True, однако на самом деле выводит False.

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

Для того, чтобы избежать этого, при сравнивать числа с плавающей точкой нужно с учётом погрешности, вот так:


C#
1
2
3
4
5
6
7
8
1static void RightMain()
2{
3    double x = 1.0 / 10;
4    double sum = 0;
5    for (int i = 0; i < 10; i++)
6        sum += x;
7    Console.WriteLine(Math.Abs(sum - 1) < 1e-9);
8}
Здесь мы проверяем, что числа равны не в точности, но что модуль их разности меньше некоторого маленького числа. Всегда используйте такую конструкцию при сравнении чисел с плавающей точкой.
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 3
Комментарии
  1. Старый комментарий
    Это верно для любого языка программирования. Мало того, даже вычисления на бумаге с помощью шариковой ручки подчиняются этому правилу.
    Запись от wer1 размещена 11.01.2019 в 09:46 wer1 вне форума
  2. Старый комментарий
    Цитата Сообщение от нтч
    Это верно для любого языка программирования. Мало того, даже вычисления на бумаге с помощью шариковой ручки подчиняются этому правилу.
    Да, все верно. Но когда пишешь ручкой на бумаге, обычно это десятичная система счисления, где человеку сразу видны места, в которых будет ошибка округления и ее можно увидеть и учесть.
    А когда пишешь
    а = 0.1;
    b = 872782577.12544;
    c = 10.0;

    Ожидаешь, что
    a * b * c будет равно b

    и даже в голову не приходит по началу, где здесь может быть ошибка.
    Запись от Orsanka размещена 11.01.2019 в 10:07 Orsanka вне форума
  3. Старый комментарий
    Цитата Сообщение от Orsanka
    а = 0.1;
    b = 872782577.12544;
    c = 10.0;

    Ожидаешь, что a * b * c будет равно b
    и даже в голову не приходит по началу, где здесь может быть ошибка.
    Вы тысячу раз правы. Если предположить, что число а задано приближенно с абсолютной погрешностью 0,05, то результат умножения будет ошеломителен: 900 000 000. Ведь относительная погрешность первого числа равна 50% (число находится на интервале (0,05; 0,15)). Другими словами, даже первая цифра результата сомнительна.
    Запись от wer1 размещена 12.01.2019 в 08:35 wer1 вне форума
 
Новые блоги и статьи
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru