Я прошу прощения, если пишу какую-то тривиальщину.
Если в ходе вычислений возникли ошибки округления, величина которых "забивает" требуемую точность, то и "abs(a)<epsilon" не поможет.
Допустим, что заведомо известно, что ошибки округления не забивают требуемую точность. Все равно, в этом случае никто и никогда не будет писать "if (x==0) ...". Проверка условия
означает, что этот случай надо рассмотреть отдельно, потому что какая-то часть алгоритма при этом разваливается; например, в процессе происходит деление на
. Но тогда очевидно, что алгоритм точно так же развалится при маленьком, но ненулевом
, потому что результат деления на
не влезет в тип данных. Поэтому в любом алгоритме, работающем с вещественными числами, проверки
заменяются на
; при этом
выбирается так, чтобы алгоритм еще работал, например, при
.
Насколько я понимаю, именно подобные вещи формализуются с помощью теории вычислимости.
Если же хотя бы один старший десятичный знак вычисляемого действительного числа найден достоверно, то сравнить это число с нулем может даже шестиклассник.
Если найден достоверно, то да. Но это как раз вещь, которую, вообще говоря, нельзя найти достоверно. Т. е. нельзя придумать алгоритм, который за гарантированное число шагов отвечает "да/нет" на вопрос "верно ли, что
". Тем более нельзя, вообще говоря, достоверно найти старший десятичный знак.
С другой стороны, существует алгоритм, который за гарантированное число шагов выдает один из двух ответов: "заведомо
" или "заведомо
". В этом случае есть интервал, в котором ответ может быть любым из двух, но это не проблема: при первом варианте алгоритм заругается на некорректные входные данные (что будет правильно, если это отразить в спецификации), а при втором варианте он запустится и выдаст правильный ответ с нужной погрешностью (если эту ветвь сделать с некоторым запасом).