Добрый день! Есть элементарная функция, которая сравнивает два числа. Почему-то там где должно быть равенство показывается ЛОЖЬ. См. скрин http://prntscr.com/nrucgm Или вложенный файл. Дело в формате ячеек или еще в чем-то другом? Заранее спасибо!
Спасибо! Тогда буду перед сравнением округлять. А вообще, с этой проблемой я столкнулся, работая с достаточного крупными суммами. И такие "приколы" - как нож в спину, для обычных пользователей.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Это не ошибка, а следствие того, что все числа, не являющиеся целыми и не представимые в виде дроби, числитель и знаменатель которой целые числа и знаменатель не является степенью двойки, хранятся в памяти процессора приближенно. Например, одна десятая. Естественно, когда вы над ними производите алгебраические операции, то может возникнуть погрешность. Поэтому на всех языках программирования (и во всех операционных системах) числа типа double (не целые) надо сравнивать так:
Код
ABS(a-b)<EPS
где погрешность EPS подбирается, исходя из специфики задачи. Для сумм в любой валюте можно, например, можно взять 1E-4.
OFF Ігор Гончаренко, sokol92, господа-буквоеды, ну камон — понятно же, что vikttur имел ввиду Если уж на то пошло, то 10,8-10,7 =0,1. А если Excel считает, что это не так (а, например, 0,100000000000001), то это неправильно, погрешность инструмента, если угодно, но всё-равно ОШИБКА. На контрольной не прокатит
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Алексей, еще пару слов после прочтения сегодняшного анекдота.
Предположим, что у Вас есть калькулятор с двумя десятичными знаками после запятой. В нем число 1/3 будет записано как 0,33. Вас нисколько не удивляет погрешность в последнем знаке после умножения на 3, так как Вы знаете, что 1/3 нельзя представить в виде десятичной дроби с конечным числом знаков после запятой (и, тем более, с двумя).
Точно так же, 1/10 не может быть представлена точно в типе double (как как раскладывается в бесконечную периодическую дробь в двоичной системе счисления). Всё, точка, мы перешли в мир приближенных вычислений. Это тоже комфортный мир, если знаешь правила проживания. Равенство чисел означает в этом мире равенство с учетом возможной погрешности округления (пример из #7). Хотите, чтобы Excel показывал Вам числа без учета округлений в последних разрядах - применяйте "числовой" формат ячеек. Общий формат ячеек не очень подходит для дробных чисел - Excel не знает, а вдруг для Вас крайне важна последняя 1 после запятой в примере из #8.
Когда Вы в Excel и/или VBA применяете функцию Round и округляете число до какого-то числа знаков после десятичной запятой, то Вы получаете не точное значение, а приближенное с минимально возможной для типа double погрешностью (кроме дробей со знаменателем, равным степени 2).
Поэтому не в стандартах дело, а в приближенных вычислениях...
sokol92, анекдот хороший))) Насчёт ошибка или нет - я не про алгоритм, а про результаты его работы на практике. Я считаю, что рядовой пользователь совершенно не обязан знать алгоритмы двоичной арифметики, чтобы отнять 2 числа с 1 знаком после запятой или, как сказал Дима: «Хочется верить, что хоть когда-нибудь описанную особенность стандарта IEEE754 Microsoft сможет победить или хотя бы сделать заплатку, которая будет производить простые вычисления не хуже 50-рублевого калькулятора :)»
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄