Все подпрограммы деления, приведенные в предыдущем разделе, возвращают на выходе результат в виде целочисленных частного Z и остатка R
X = 11, Y = 4,
X/Y = Z + R,
11/4 = [2] + {3}.
Однако при попытке продолжить деление, по аналогии с подобным действием в десятичной системе, что иногда бывает необходимо на практике, мы получим частное, представленное в форме дробного числа с фиксированной запятой
X = 11, Y = 4,
X/Y = Z + R,
11/4 = 0b10.11
Работа с такими числами ни чем не отличается от работы с неотрицательными целыми числами. Разница состоит лишь в том – где фиксируется дробная часть результата. Так результат деления 11/4 дал целую часть числа 2 и дробную (отделённые младшие два разряда) 0.75. Теперь если вам потребуется использовать этот результат в последующих арифметических операциях, то нужно просто запомнить где находится разделяющая запятая и соответственно определить веса каких разрядов 2n, а каких 1/2m. Тоже число 0b1011 может трактоваться по-разному в зависимости от того сколько разрядов отведено под целую и дробную части
0b1.011 = 1*20 + 0*(1/21) + 1*(1/22) + 1*(1/23) = 1.375 (формат (1.3)),
0b10.11 = 1*21 + 0*20 + 1*(1/21) + 1*(1/22) = 2.750 (формат (2.2)),
0b101.1 = 1*22 + 0*21 + 1*20 + 1*(1/21) = 5.500 ( формат (3.1)) и т.д.
Рассмотрим как можно, например, сложить два дробных числа, предварительно приведя их к одному виду:
11/4 + 7/8 = 0b1011/0b0100 + 0b0111/0b1000 = 0b1011 >> 2 + 0b0111 >> 3 = 0b10.11 + 0b0.111 = 0b10.110 + 0b00.111 = 0b11.101 = 3.625
Дробные двоичные слагаемые 0b10.11 = 2.750 (формат (2.2)) и 0b0.111 = 0.875 (формата (1.3)) были приведены к единому формату представления (2.3) (0b10.110, 0b00.111), где целую и дробную части отделяют запятая между третьим и четвёртым разрядами. После этого мы их сложили, как два обыкновенных семизначных числа. Итак, дробные числа с фиксированной запятой – подчиняются всем тем же законам двоичной арифметики, что и целые числа.
В случае использования дробных чисел с фиксированной запятой в промежуточных вычислениях необходимо заранее ограничить разрядность дробной части результата. Это обусловлено тем, что при делении возможно образование бесконечных дробей, как допустим, 179/9 = 0b1001.100001… = 10.515625….
Округление двоичных чисел происходит точно так же, как и в десятичной системе исчисления. Если дробный остаток от деления ≥0.5 (т.е. если старший разряд в остатке, вес которого как раз 1/21, равен 1) или целочисленный остаток R≥0,5*Y , то частное Z округляется в большую сторону. Так при делении 9/2 = 0b100.1 = 4.5 необходимо учесть дробную часть 0.5 и округлить частное до 5, а, например, при делении 9/4 = 0b10.01 = 2.25 остаток 0.25 надо отбросить.
Другим способом произвести корректировку частного можно, если добавить к нему 1/2. Тогда можно будет свободно отбросить остаток, поскольку округление в большую сторону будет происходить каждый раз, когда R≥0,5. Добавление 1/2 к частному равносильно добавлению перед делением к делимому половины делителя
(X + Y/2) / Y = X/Y + 1/2 = Z + 1/2.
Подпрограмма, приведенная ниже вносит такую поправку перед делением 15-разрядного делимого на 8-разрядный делитель.
; R17:R16 + R18 / 2 = (2*R17:R16 + R18) / 2 ; R17:R16 – делимое, подлежащее корректировке ; R18 – делитель ; R19 – вспомогательный регистр cor_div: clr R19 ;обнуляем R20 lsl R16 ;умножение 2*R17:R16 rol R17 add R16,R18 ;сложение 2*R17:R16 + R18 adc R17,R19 ror R17 ;деление (2*R17:R16 + R18)/2 ror R16 adc R16,R19 ;корректируем (2*R17:R16 + R18)/2 adc R17,R19 ;если остаток ≥0,5 ret
Перейти к следующей части: Знаковые целые числа - Особенности работы со знаковыми числами
Комментарии (0) | Я собрал (0) | Подписаться
Для добавления Вашей сборки необходима регистрация