К примеру, дробь 1/3 можно приближенно выразить следующим образом.
1/3 = 1/2 - 1/4 + 1/8 - 1/16 + 1/32 - 1/64 + 1/129...
На основе этого рада напишим программу, которая будет делить число N, находящееся в рабочем регистре, на три,
помещая частное в тот же регистр.
Временные переменные для хранения частного и количества сдвигов можно использовать регисры h20 и h21.
Байт частного, а число из W копируется в регистр h21.
После этого исходное число сдвигается в право для получения различных дробей, которые либо прибавляются,
либо вычитаются из регистра h20, постепенно формируя искомое частное.
При последнем члене ряда, равном 1/129, результат равен 0, 3359375, отклонение от точного значения составляет 0. 78% .
При работе с 8-битными числами включать в ряд остальные члены не имеет смысла.
Если же необходима большая точность, то исходное значение следует расширить до 16 бит, добавив младший нулевой байт.
Используя при этом 2 - байтные арифметические операции и операции сдвига, можно будет у величить число членов
ряда и получить точность вплоть до 1/32768.
Деления на три.
QUOTIENT equ h20; Временная переменная для хранения частного
TEMP equ h21; Временная переменная для операий сдвига
STATUS equ 3; Регистр STATUS
C equ 0; Бит 0 - флаг переноса
DIV_3 сlrf QU0TIENT; Обнуляем результат
movwf TEMP; ПОМЕЩАЕМ N во временный регистр
bcf STATUS, C; Сбрасываем флаг переноса
rrf TEMP, f; Сдвигаем вправо, получаем N/2
movf TEMP, w; Копируем в W
movwf QUOTIENT; и в QUOTIENT, получаем Q = N/2
bcf STATUS, C; Сбрасываем флаг переноса
rrf TEMP, f; Сдвигаем вправо, получаем N/8
movf TEMP, w; Копируем в W
addwf QUOTIENT, f; Складываем, получаем Q = N * ( 1/2 - 1/4 + 1/8)
bcf STATUS, C; Сбрасываем флаг переноса
rrf TEMP, f; Сдвигаем вправо, получаем N/16
movf TEMP, w; Копируем в W
subwf QUOTIENT, f; Вычитаем, получаем Q = N * ( 1/2 - 1/4 + 1/8 - 1/16 )
bcf STATUS, C; Сбрасываем флаг переноса
rrf TEMP, f; Сдвигаем вправо, получаем N/32
movf TEMP, w; Копируем в W
addwf QUOTIENT, f; Складываем, получаем Q = N * ( 1/2 - 1/4 + 1/8 - 1/16 + 1/32 )
bcf STATUS, C; Сбрасываем флаг переноса
rrf TEMP, f; Сдвигаем вправо, получаем N/64
movf TEMP, w; Копируем в W
addwf QUOTIENT, f; Складываем, получаем Q = N * ( 1/2 - 1/4 + 1/8 - 1/16 + 1/32 - 1/64
bcf STATUS, C; Сбрасываем флаг переноса
rrf TEMP, f; Сдвигаем вправо, получаем N/64
movf TEMP, w; Копируем в W
addwf QUOTIENT, f; Складываем, получаем Q = N * ( 1/2 - 1/4 + 1/8 - 1/16 + 1/32 - 1/64 + 1/128 )