Десятичное сравнение двоичных чисел

Смысл любых математических вычислений – ответить на вопросы: равно ли  одно число другому и если не равно, то на сколько, или во сколько раз они отличаются друг от друга. Ответить на вопрос, какое из чисел больше или меньше не составляет труда, если есть ответ на вопрос, равны или нет сравниваемые числа. А ответить на вопрос о равенстве чисел не очень просто в рамках двоичной  компьютерной арифметики.

Как известно, вся классическая математика развивалась из десятичного представления счета. Человек привык мыслить в десятичной системе счисления, хотя она мало чем отличается от любой другой системы. Современные компьютеры работают в основном  в двоичной системе счисления, т.к. технически реализовать двоичную арифметику гораздо проще. Тем не менее, в силу привычки, мы, как правило, интерпретируем двоичные результаты вычислений в десятичном счислении. Поэтому, проводя вычисления над десятичными числами на компьютере, мы, по факту, можем говорить о десятично-двоичной арифметике. А поскольку десятичная и двоичная системы счисления несоизмеримы, то на результаты вычислений, кроме ошибок вычисления, связанных с двоичным округлением,  будут оказывать ошибки преобразования чисел из десятичного вида в двоичный. 

Итак, в десятично-двоичной арифметике десятичные вычисления выполняются в двоичном коде. Наиболее удобное представление чисел, используемое в  двоичных вычислениях в компьютере, является представление чисел в виде чисел с плавающей точкой (ЧПТ).   Стандарт IEEE754 предписывает все вычисления вести, в основном, с двоичными ЧПТ в  нормализованном виде. И только в редких специфических случаях предполагается использование ненормализованных, так называемых, субнормальных чисел. В таком представлении, каждому десятичному числу, с определенным количеством N значащих цифр однозначно ставится в соответствие двоичное число, с заданным количеством разрядов p и экспонентой e. Число p – это точность представления.

Например, десятичному числу x*(2) = 0.021 с N = 2 значащими цифрами при конвертации однозначно ставится в соответствие двоичное число y*(8) = 1.0101100·2-6  с точностью p = 8.  Ближайшее к нему меньшее двухразрядное десятичное число x_=0.020 в двоичном коде с p=8 значащими цифрами равно y_= 1.0100100·2-6, а ближайшее большее число x = 0.022 равно y= 1.0110100·2-6. Отсюда видно, что при конвертации десятичного числа x*(2)  с N = 2 значащими цифрами в двоичный код с p = 8 значащими цифрами, мы получаем уникальный двоичный  код y*(8). Важно отметить, что, при фиксированном p,  для большего количества значащих цифр n в первичном десятичном числе x(n) это утверждение может быть не верно. Действительно, десятичному числу x(4) = 0.02201 соответствует двоичное число 1.0110100·2-6 с p=8, которое совпадает с двоичным кодом числа 0.022.

Если теперь решать обратную задачу, ставя в соответствие двоичному коду y(p) десятичное число x(N), мы однозначного соответствия не получим. Действительно, число y1(8) = 1.0101100·2-6 = x1(10) = 0.02099609375. А ближайшее к нему  большее двоичное число y2(8) = 1.0101101·2-6 =  x2(12) = 0.0211181640625. Мы видим, что для обоих этих представимых десятичных чисел x1(10) и x2(12) ближайшим двухзначным десятичным числом будет число x*(N) = 0.021. Но ведь числу 0.021 однозначно соответствует только одно двоичное число с заданным p. Здесь мы сталкиваемся с так называемой «дилеммой составителя таблиц». Из возможных вариантов двоичных чисел мы должны выбрать одно, десятичное значение которого ближе всего к верному.

С точки зрения десятичной арифметики, для приближенных вычислений, выполняемых с точностью до N = 2 значащих десятичных чисел, сравнению подлежат не два числа x1(10) и x2(12), а числа, которые  округлены до двух значащих цифр с погрешностью < 0.0005. Для обоих округляемых чисел это будет число 0.021.  Поэтому  логично предположить, что разность x1(10) — x2(12) должна быть равна нулю с погрешностью < 0.0005. Но если вычесть двоичные эквиваленты этих двух представимых чисел y1(8) — y2(8), то нуля мы не получим. То есть, сравнение на строгое равенство покажет, что наши представимые числа не равны.  

Отсюда следует вывод. Чтобы сравнить два двоичных числа, они должны быть приведены к числу, которое является двоичным эквивалентом правильно округленного до x*(N) десятичного числа. В этом случае при вычитании мы получим строгий нуль.

Заметим, что сравнивать с заданной десятичной погрешностью можно двоичные числа, представленные с любой точностью, например, числа представленные в форматах float и doubl. Но при этом нужно выполнить два требования. Первое – округленные числа перед сравнением  должны быть приведены к одному формату. Второе – чтобы количество двоичных разрядов двоичных чисел было достаточно для гарантированного  представления всех N цифр десятичных чисел. Так, для  float – это 7 десятичных цифр, а для doubl – это 15 десятичных цифр.

Я изобретатель, имею 18 авторских свидетельств СССР на изобретения и два патента. Последние несколько лет занимаюсь исследованием проблем компьютерной математики.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *