Байт на 3 еще проще - умножь его на 171 (= 0xAB), реультат = старший байт произведения, сдвинутый на 1 бит вправо В общем случае нужно сначала прикинуть требуемое число ЗНАЧАЩИХ (т.е. начиная с самой левой единицы) бит множителя - она должна быть на один бит меньше, чем сумма разрядностей максимального результата и делителя. Например, при делении байта на три максимальный результат (255/3=85) семибитный, делитель (3) - двухбитный, итого 7+2-1=8 ЗНАЧАЩИХ бит (т.е. множитель должен быть >= 128).
Теперь находим множитель. Он должен представлять собой некое число, ДВОИЧНО обратное тройке (т.е. вида 2^N/3). Прикидываем его минимальное значение - 128*3=378, значит, выберем 2^N=512. Делим 512 на 3, получаем 170.666(6), округляем до целого 171 - вот и множитель.
Так как мы вынуждены были взять 2^N=512, то после умножения на наш множитель старший байт результата нам придется еще разделить на 2 (сдвинуть на один бит вправо) - если бы N было кратно 8, то этого не потребовалось бы.
Итого для MegaAVR получаем всего 4 такта:
<asm>
; Input: r1 = X
; Output: r1 = X/3
div3:
ldi r16,(512/3)+1
mul r1,r16 ; r1:r0 =~ X*512/3
lsr r1 ; r1 = ((X*256)/3)/256 =~ X/3
</asm>
Так как рассматривался общий случай, то замечу - в конкретных случаях часто бывает можно уменьшить число значащих бит множителя еще на 1. Вроде бы для div3 можно обойтись умножением на 86 и взятием старшего байта безо всяких сдвигов, но надо проверять. Все зависит от того, насколько велика ошибка округления от 2^N/div#.
В этом случае для MegaAVR получаем всего 3 такта:
<asm>
; Input: r1 = X
; Output: r1 = X/3
div3:
ldi r16,(256/3)+1
mul r1,r16 ; r1:r0 =~ X*256/3, r1 = ((X*256)/3)/256 =~ X/3
</asm>
Почитать можно, например, на сайте HackersDelight - http://www.hackers …HDcode/newCode/divuc.c , а вся книга издана на русском, очень рекомендую - http://www.hackers …org/RussianHDCover.jpg http://www.rsdn.ru …s/book/prog/worren.xml
-
- Спасибо...то что нужно!!! - Aleksey75(28.01.2007 16:23, )