Снова о числах с плавающей точкой
Несмотря на то, что вопросам точности компьютерных вычислений посвящено очень много публикаций, некоторые из них, на наш взгляд, всё же остаются не до конца четко раскрытыми. А именно:
1. Какое количество верных цифр n гарантированно имеет десятичное число, представленное двоичным m разрядным кодом в формате числа с плавающей точкой.
2. Как влияет нормализация чисел с плавающей точкой на точность представления числа при его преобразовании из одной системы счисления в другую и при арифметических действиях, выполняемых на компьютере.
3. Как влияет округление числа, представленного в двоичном виде на его десятичный эквивалент.
4. Как положение виртуальной точки в машинном слове влияет на значение числа, представленного в экспоненциальной форме.
Ниже мы попытаемся ответить на эти вопросы.
В своих рассуждениях мы будем исходить из представлений о числах с позиции классической арифметики. Нами будут рассмотрены числа, количество значащих цифр которых ограничено разрядной сеткой машинного слова. Чтобы упростить изложение будем рассматривать только положительные числа.
Как правило, прежде чем производить какие либо арифметические операции на компьютере над десятичными числами, их представляют в дробном двоичном виде в естественной форме, а затем записывают полученные числа в нормализованном экспоненциальном виде:
F=M*2^-p,
где М — мантисса двоичного числа, 2^-p — характеристика числа, ее еще часто называют экспонентой, p — порядок характеристики.
Двоичное число, представленное в десятичном виде, будем называть двоичным эквивалентом десятичного числа. Десятичное число, представленное в двоичном виде, будем называть двоичным эквивалентом десятичного числа.
Если в качестве мантиссы М принять естественную запись числа, то порядок характеристики в приведенной формуле будет равен нулю, а характеристика, соответственно, единице. Мы будем иметь число, представленное как F = M*2^0=M. Например, двоичное число F= 0.011 имеет порядок p=0. Если точку в числе условно поставить перед старшей значащей цифрой, то порядок характеристики p=-1 и F=0.11*10^-1. Если точку в числе условно поставить сразу после старшей значащей цифры, то порядок p=-2 и F=1.1*10^-2. Если виртуальную точку поставить после младшего разряда мантиссы М, то мантисса будет целым числом и для нее p=-3, а F=11*10^-3. Как мы видим, во всех случаях порядок характеристики равен количеству смещений виртуальной точки в числе относительно ее положения в естественной записи. Все виды записи в наших примерах эквивалентны и имеют одно и то же значение.
Таким образом, значение показателя характеристики числа, представленного в экспоненциальном виде, с учетом положения виртуальной точки, определяет место точки в числе, записанном в естественном виде.
Разрядность машинной мантиссы однозначно определяет количество десятичных чисел, которое может быть представлено в этой мантиссе в двоичном виде. А положение виртуальной точки в мантиссе определяет область на числовой оси, где располагаются эти числа. Двоичные числа, количество значащих цифр которых не превышает количества разрядов машинной мантиссы, являются точными, а десятичные числа, полученные конвертацией этих двоичных чисел в десятичные, называются представимыми.
В силу того, что не все значащие цифры двоичного числа могут уместиться в разрядную сетку машинной мантиссы, это число округляют до необходимого количества значащих цифр. Такое число иногда называют округленным до ближайшего представимого. Округленное двоичное число становится приближенным.
Не смотря на то, что все двоичные числа являются эквивалентом представимых десятичных чисел, не все десятичные числа можно представить в машинном слове. Это связано с несоразмерностью десятичной и двоичной систем счисления. Поэтому десятичные числа, в основном, могут быть представлены в двоичном виде приближенно, в то время как все двоичные числа могут быть представлены в десятичном виде точно. Или, другими словами. Двоичный эквивалент десятичного числа конечной длительности может содержать бесконечное количество значащих цифр. Десятичный эквивалент двоичного числа конечной длительности содержит конечное число значащих цифр.
Приближенные числа состоят из верных (в широком смысле) и неверных цифр. Неверные цифры при арифметических действиях искажают конечный результат. Чтобы этого не происходило, приближенные числа округляют до ближайшей верной цифры.
Округление двоичных чисел приводит к уменьшению учитываемых верных цифр в округленном числе и к изменению неверных цифр в его десятичном эквиваленте. Неверные цифры образуют абсолютную погрешность преобразования.
Округление двоичного числа до ближайшего представимого приводит к увеличению погрешности представления десятичного эквивалента этого числа. Это связано с тем, что при округлении двоичного числа уменьшается количество значащих двоичных цифр, участвующих в представлении его десятичного эквивалента.
В результате преобразования десятичного числа в двоичное, с заданным количеством значащих цифр, получается двоичное число, десятичный эквивалент которого будет приближенным числом, содержащим как верные, так и неверные цифры.
Определим, какое количество верных цифр n гарантированно имеет десятичное число, представленное двоичным m разрядным кодом в формате числа с плавающей точкой.
Если в машинном слове для записи мантиссы числа выделено m двоичных разрядов, то максимальное целое число, которое можно записать в такую мантиссу будет равно Fmax= (2^m)-1. Все m цифр в этом числе имеют значение 1. Для m=8, например, Fmax = 2^8 — 1= 255=111111112. Пусть теперь мы имеем целое десятичное число с n значащими цифрами. Максимальное десятичное число, имеющее n значащих цифр, будет состоять из цифр, каждая из которых равна 9. Таким образом, максимальное десятичное число с n значащими цифрами может быть записано как Fmax=(10^n)-1. Например, для n=2, Fmax=10^2 -1=99.
Для того чтобы десятичное число с n значащими цифрами гарантированно было представлено двоичным кодом с мантиссой, имеющей m разрядов, должно выполняться условие: (10^n)-1 ≤ (2^m)-1 или 10^n ≤ 2^m. Откуда log1010^n≤ log102^m или n≤ m log102. Поскольку log102≈0.3, то будет справедливо неравенство n≤0.3m. Поскольку числа m и n целые, для них будет справедливо неравенство
n≤⌊0.3m⌋. Так, для m=8, будем иметь n≤⌊0.3*8⌋=2.
До сих пор мы говорили о целочисленной машинной мантиссе. На практике же принято считать машинную мантиссу дробным числом с виртуальной точкой, стоящей перед старшим разрядом. Эта виртуальная точка преобразует целое число, записанное в машинной мантиссе в дробное число. Преобразование целого двоичного числа с m значащими цифрами в число, которое представляет собой правильную дробь, равносильно умножению этого числа на коэффициент 2^-m. Таким образом, если в каждом разряде m разрядной машинной мантиссы записаны только единицы и при этом предполагается, что виртуальная точка стоит в начале мантиссы, то число, представленное в этой мантиссе, будет максимальным и будет равно Mmaxd = 1-2^-m. Где Mmaxd — максимальное дробное число, которое может быть представлено в m разрядной машинной мантиссе с виртуальной точкой в начале мантиссы.
С другой стороны, если машинную мантиссу считать целочисленной, т.е. полагать, что виртуальная точка стоит сразу за младшим разрядом машинной мантиссы, то максимальное целое число Mmaxc, которое в нее можно записать, будет состоять из одних единиц и равно Mmaxc = (2^m)-1. Если теперь точку переместить в начало мантиссы, то это будет равносильно тому, что Mmaxd= Mmaxc*2^-m.
Таким образом, в m разрядную машинную мантиссу можно записать дробные числа, лежащие в диапазоне от 0 до Mmaxc*2^-m. Где Mmaxc — максимальное целое двоичное число, которое помещается в машинную мантиссу.
В общем случае от выбора виртуальной точки зависит только значение порядка характеристики числа, представленного в экспоненциальном виде. Само же значение числа остается неизменным.
Например, в трехразрядную машинную мантиссу можно записать максимальное целое число 1112 = 7. Это число с виртуальной точкой перед старшим разрядом машинной мантиссы будет иметь значение 0.111=7*2^-3= 0,875. Записанное в машинной мантиссе число 1012 = 5 с виртуальной точкой перед старшим разрядом будет иметь значение 0.1012=5*2^-3= 0,625 и т.д.
В разных источниках в настоящее время высказываются различные мнения о точности представления десятичных чисел в двоичном коде. Не затрагивая здесь вопроса точности двоичных арифметических операций над десятичными числами, представленными в двоичном виде, рассмотрим точность конвертации десятичных чисел в двоичные.
В англоязычной википедии [5], относительно формата doabl говорится, что в 53 разрядной машинной мантиссе можно представить 15-17 разрядное десятичное число. Однако выше мы вывели формулу, согласно которой в 53 разрядной мантиссе можно гарантировано представить десятичное число, имеющее количество значащих цифр n≤⌊0.3*53⌋ = 15. Действительно, максимальное целое двоичное число, которое может быть записано в 53 разрядную мантиссу, будет состоять из 53 единиц. Его десятичное значение будет равно (2^53) -1= 9007199254740991. Это число имеет 16 значащих десятичных цифр. Если прибавить к нему единицу, количество значащих цифр десятичного числа не изменится, оно будет равно 16, а вот двоичное представление этого, увеличенного на единицу десятичного числа, уже будет содержать на 1 значащую цифру больше. Поэтому, не все 16-ти разрядные десятичные числа могут быть представлены 53-х разрядной машинной мантиссой. В то же время, в такой двоичной мантиссе гарантированно можно представить все десятичные числа с количеством значащих цифр не более чем 15. Для гарантированного же представления десятичного числа с 17 значащими цифрами требуется машинная мантисса с количеством разрядов не менее 57, т.к. ⌊0.3*57⌋=17.
Для того чтобы рассмотренные в примерах выше целочисленные мантиссы сместить в область дробных чисел, надо все числа умножить на масштабный коэффициент 2^-53. Тогда максимальное двоичное дробное число в 53-х разрядной машинной мантиссе будет иметь вид:
0.11111111111111111111111111111111111111111111111111111 = 11111111111111111111111111111111111111111111111111111 *2^-53= 9007199254740991*2^-53= 0,99999999999999988897769753748435. Жирным шрифтом помечены верные цифры, соответствующие значащим десятичным цифрам максимального пятнадцатизначного дробного десятичного числа.
Чтобы десятичное число было преобразовано к двоичному виду максимально точно, необходимо, чтобы в двоичном представлении десятичного числа было учтено как можно больше значащих цифр. В идеале, количество значащих цифр двоичной мантиссы числа должно быть равно количеству разрядов машинной мантиссы. Для этой цели десятичное число разлагают по степеням двойки до тех пор, пока количество значащих цифр двоичного числа не сравняется с количеством разрядов машинной мантиссы или не будет разложено точно. Полученное таким образом число нормализуют, смещая старшую значащую цифру числа в старший разряд машинной мантиссы. А в машинную область порядка характеристики помещают масштабный коэффициент, равный количеству сдвигов старшей значащей цифры числа. Процедура нормализации никак не меняет значение числа, а следовательно и точность его представления.
Для примера возьмем компьютер с 8-ми разрядной мантиссой. Гарантированное количество значащих десятичных цифр, которое можно представить в 8-ми разрядной машинной мантиссе равно n ≤ ⌊0.3*8⌋=2. Пусть нам дано число 0.0012. Это число в двоичном виде будет равно ≈ 0.00000000010011101010010. Округлим это число до 8 значащих цифр, количество которых соответствует размеру разрядной сетки машинной мантиссы. Получим число 0.00000000010011101= 0.00119781494140625≈0.0012. Нормализуем это число, поместив в машинную мантиссу все значащие цифры мантиссы числа. Получим 0.00000000010011101010010= 0.10011101*2^-9 = 0,61328125*2^-9=0,00119781494140625. Как мы видим, значение числа не изменилось после нормализации. Точность представления числа также не изменилась, т.к. количество значащих цифр после нормализации осталось неизменным. Мы просто получили другую форму записи одного и того же числа.
В случае если при нормализации двоичного числа окажется, что количество сдвигов старшей значащей цифры числа превышает количество разрядов машинной области, которая предназначена для записи порядка характеристики числа, то число не может быть записано в нормализованном виде. В этом случае происходит потеря точности за счет того, что часть, или все значащие цифры числа оказываются за пределами разрядной сетки машинной мантиссы.
В том случае, когда в результате арифметической операции получено двоичное число, все значащие цифры которого расположены в пределах машинной мантиссы, нормализация результата, с точки зрения арифметики, не имеет смысла.
Например, пусть мы имеем компьютер с 8-ми разрядной машинной мантиссой, в котором виртуальная точка размещена перед старшим разрядом мантиссы. Найдем разность двух двоичных чисел: 0.10110000-0.10010011=0.00011101. Значащие цифры разности полностью поместились в разрядную сетку машинной мантиссы. Десятичный эквивалент этой разности будет равен 0.6875-0.57421875=0.11328125. Нормализуем число 0.00011101. Будем иметь 0.00011101=0.11101*2^-3=0.90625*2^-3=0.11328125. Мы видим, что нормализация никак не изменила значения разности чисел и поэтому в дальнейших вычислениях эти две записи результата, с точки зрения математики, эквивалентны.
СУХОЙ ОСТАТОК
Любое число можно представить в экспоненциальном виде с виртуальной точкой, расположенной в любом месте мантиссы. Смещение точки от ее естественного положения записывается в область машинного слова, выделенную для записи порядков характеристик.
Разрядность машинной мантиссы определяет количество десятичных чисел, которое может быть представлено в этой мантиссе. А положение виртуальной точки в мантиссе определяет область на числовой оси, где располагаются эти числа.
Положение виртуальной точки никак не влияет на точность представления числа.
Точность представления двоичного числа зависит от количества значащих цифр мантиссы, которое можно записать в машинное слово.
Все двоичные числа являются эквивалентом представимых десятичных чисел. Десятичные числа не все являются представимыми в машинном слове. Десятичные действительные числа, в основном, могут быть представлены в двоичном виде приближенно, в то время как все двоичные числа могут быть представлены в десятичном виде точно.
Округление двоичных чисел приводит к уменьшению учитываемых верных цифр в округленном двоичном числе, за счет отбрасывания цифр, не вместившихся в разрядную сетку машинной мантиссы и, как следствие, к уменьшению точности представления десятичного эквивалента.
Округление двоичных действительных чисел приводит к изменению неверных цифр в их десятичном эквиваленте, но не к ликвидации неверных десятичных цифр.
Неверные десятичные цифры в десятичном эквиваленте двоичного числа, полученного из точного десятичного числа, образуют абсолютную погрешность преобразования.
В машинной мантиссе с m разрядами можно гарантированно представить десятичное число, количество верных цифр в котором n≤⌊0.3m⌋.
Нормализация двоичных чисел никак не меняет значения числа, если она осуществляется без округления.
Нормализация не влияет на точность представления числа, если она осуществляется без округления.
ИСТОЧНИКИ
1. «Что нужно знать про арифметику с плавающей запятой»
2. Всё, точка, приплыли! Учимся работать с числами с плавающей точкой и разрабатываем альтернативу с фиксированной точностью десятичной дроби.
3. «Компенсация погрешностей при операциях с числами с плавающей запятой»
4. «Вычисления с плавающей точкой: можно ли доверять результатам?»
5. Wikipedia
6. www.softelectro.ru/ieee754.html
7. «Нужна ли нормализация в числах с плавающей точкой»