Часто при вычислении разницы двух ячеек в Excel можно видеть, что она не равна нулю, хотя числа одинаковые. Например, в ячейках
И самое странное то, что в итоге мы не получаем 0! Почему?
И еще одна ситуация - я её называю "Куда пропала копейка?!". На скрине ниже изображена достаточно частая ситуация в Excel:
Слева числа получены формулами и сложены в единую сумму при помощи функции
Разберем причины подобного поведения и главное - как эту проблему можно решить.
Сначала самый очевидный ответ: если идет сравнение значений двух ячеек, то необходимо убедиться, что числа там действительно равны и не округлены форматом ячеек. Например, если взять те же числа из примера выше, то если выделить их -правая кнопка мыши -Формат ячеек
Теперь все становится очевидным - числа отличаются и были просто округлены форматом ячеек. И естественно не могут быть равны. В данном случае оптимальным будет понять почему числа именно такие, а уже потом принимать решение. И если уверены, что числа надо реально округлять до десятых долей - то можно применить в формуле функцию ОКРУГЛ:
Но как быть, если таких формул десять, двадцать и более? Не прописывать же вручную для каждой формулу ОКРУГЛ. Можно использовать одну из функций моей надстройки MulTEx, которая двумя кликами мыши все сделает за вас. Достаточно будет выделить все ячейки с "неверными" числами, которые надо округлить, перейти на вкладку
Но есть и
Excel 2007: Кнопка офис -Параметры Excel(Excel options) -Дополнительно(Advanced) -Задать точность как на экране(Set precision as displayed) Excel 2010: Файл(File) -Параметры(Options) -Дополнительно(Advanced) -Задать точность как на экране(Set precision as displayed) Excel 2013 и выше: Файл(File) -Параметры(Options) -Дополнительно(Advanced) -Задать указанную точность(Set precision as displayed)
Это запишет все числа на всех листах книги ровно так, как они отображены форматом ячеек. Данное действие лучше выполнять на копии книги, т.к. оно приводит все числовые данные во всех листах книги к тому виду, как они отображены на экране. Т.е. если само число содержит 5 десятичных разрядов, а форматом ячеек задан только 1 - то после применения данной опции число будет округлено до 1 знака после запятой. При этом отменить данную операцию нельзя, если только не закрыть книгу без сохранения.
Но нередко в Excel можно наблюдать более интересный "феномен": разница двух дробных чисел, полученная формулой не равна точно такому же числу, записанному напрямую в ячейку. Для примера, запишите в ячейку такую формулу:
по виду результатом должен быть ответ
Сначала разберемся почему Excel считает приведенное выше выражение ложным. Ведь если вычесть из
и теперь видно, что на самом деле в ячейке не ровно
А теперь будем разбираться откуда этот "хвостик" появился, ведь и логически и математически его там быть не должно. Рассказать я постараюсь очень кратко и без лишних заумностей - их на эту тему при желании можно найти в интернете немало.
Все дело в том, что в те далекие времена(это примерно 1970-е годы), когда ПК был еще чем-то вроде экзотики, не было единого стандарта работы с числами с плавающей запятой(дробных, если по простому). Зачем вообще этот стандарт? Затем, что компьютерные программы видят числа по своему, а дробные так вообще со статусом "все сложно". И при этом одно и то же дробное число можно представить по-разному и обрабатывать операции с ним тоже. Поэтому в те времена одна и та же программа, при работе с числами, могла выдать различный результат на разных ПК. Учесть все возможные подводные камни каждого ПК задача не из простых, поэтому в один прекрасный момент началась разработка единого стандарта для работы с числами с плавающей запятой. Опуская различные подробности, нюансы и интересности самой истории скажу лишь, что в итоге все это вылилось в стандарт IEEE754. А в соответствии с его спецификацией в десятичном представлении любого числа допускаются ошибки в 15-м значащем разряде. Что и приводит к неизбежным ошибкам в вычислениях. Чаще всего это можно наблюдать именно в операциях вычитания, т.к. именно вычитание близких между собой чисел ведет к потере значимых разрядов.
Вот это как раз и является виной подобного поведения Excel. Хотя справедливости ради надо отметить, что не только Excel, а всех программ, основанных на данном стандарте. Конечно, напрашивается логичный вопрос: а зачем же приняли такой глючный стандарт? Я бы сказал, что был выбран компромисс между производительностью и функциональностью. Хотя возможно, были и другие причины.
Куда важнее другое:
По сути никак, т.к. это программная "ошибка". И в данном случае нет иного выхода, как использовать всякие заплатки вроде ОКРУГЛ и ей подобных функций. При этом ОКРУГЛ здесь надо применять не как в было продемонстрировано в самом начале, а чуть иначе:
т.е. в ОКРУГЛ мы должны поместить само "глючное" выражение, а не каждый его аргумент отдельно. Если поместить каждый аргумент - то эффекта это не даст, ведь проблема не в самом числе, а в том, что с ним происходит дальше(в примере - вычитание). И в данном случае 10,8 и 10,7 уже округлены до одного разряда и понятно, что округление отдельно каждого числа ничего не изменит. Здесь и еще один нюанс - вполне достаточно, зная эту особенность, округлить до 14 знаков и проблема тоже исчезнет. В чем здесь плюс - как правило очень мало задач для решения требуют 15 знаков после запятой и этот 15-ый можно просто "игнорировать", но при этом не убирать более значимые разряды(ведь не всегда известно до какого разряда можно округлять без потерь):
Можно, правда, выкрутиться и иначе. Умножить каждое число на некую величину(скажем на 1000, чтобы 100% убрать знаки после запятой) и после этого производить вычитание и сравнение:
Хочется верить, что хоть когда-нибудь описанную особенность стандарта IEEE754 Microsoft сможет победить или хотя бы сделать заплатку, которая будет производить простые вычисления не хуже 50-рублевого калькулятора :)
P.S. В последних версиях Excel(на моем 365, например) подобный "глюк" может проявляется уже даже не в 15-м значащем разряде, а куда раньше - даже на 11-м. Это следует учитывать при применении округлений выражения.
а еще проще заменить вычитание сложением
=10,8=10,7+0,1
Спасибо автору за разъяснения. Обнаружил ошибку при сравнении разности с числом, довел ситуацию до абсурда и выяснил, что в Excel 2013 ошибка возникает при действии с числами начиная с четвертого знака после запятой в 17-м знаке, хотя номер знака при сравнении разности с нулем не имеет значения
A B C A-B-C
1,3000000000 1,1000000000 0,2000000000 0,00000000000000000000
1,0300000000 1,0100000000 0,0200000000 0,00000000000000000000
1,0030000000 1,0010000000 0,0020000000 0,00000000000000000000
1,0003000000 1,0001000000 0,0002000000 -0,00000000000000002204
1,0000300000 1,0000100000 0,0000200000 -0,00000000000000009102
1,0000030000 1,0000010000 0,0000020000 0,00000000000000005751
Спасибо автору!
Столкнулся с такой же проблемой в Excel 2016. Только интереснее ситуация. Мне нужно было получить копейки от суммы. Я делал вычитание с огруглением. При высчтании чисел взятых прямыми ссылками возникает ошибка в шестом и седьмом разрядах после запятой. А если ссылки заменить на числа (те же что и в ячейках), то ошибка не возникает. Исходные ячейки проверял на наличие хвоста. В чем тут разница не понятно чем отличается число по ссылке от числа вбитого напрямую?
Евгений, без файла на такие вопросы практически не реально ответить. Возможно, файл формировался сторонней программой и был неверно сформирован(такое бывает с файлами из 1С). А может и еще что-то.