PDA

Просмотр полной версии : asm: x mod 3 ?



Hacker VBI
06.08.2013, 22:29
собственно сабж
x mod 2 можем сделать сдвигом || and 1
a мод 3?

Vitamin
06.08.2013, 23:30
;in A - number
;out A - number mod 3
ld c,#c0
loop:
sub c
jz exit
jnc,nxt
add a,c
nxt:
rr c
jnc,loop
exit:


но надо проверить- могу и наглючить:)

research
07.08.2013, 13:32
хм, я приблизительно умножал на 85, делил на 256 (выкидывал младший байт)
точность 1/256, вполне катит.

Hacker VBI
07.08.2013, 14:11
в общих чертах ясно.
спасибо, ребята!

Andrew771
07.08.2013, 14:36
хм, я приблизительно умножал на 85, делил на 256 (выкидывал младший байт)
точность 1/256, вполне катит.
я тоже так делаю. Самый быстрый способ. Для разных делителей только разное число, которое потом делится на 256.

research
07.08.2013, 15:22
ну да, дробные числа получаются по основанию 256. Деление на 256 - выкинуть младший байт, а умножение на константу - копеечное дело.

Жаль, в вузах нас этому не учили. Тот же Брезенхейм казался прям эдакой загадкой. Потом, когда я занялся цифровым синтезом, сам понял, что вот они, дроби (по сути).

GriV
10.08.2013, 13:20
но надо проверить- могу и наглючить
Очень красиво. Так ведь можно и на другие делители MOD делать, главное чтобы младший бит остатка был равен единице (нечётное число).

Vitamin
10.08.2013, 14:30
Очень красиво. Так ведь можно и на другие делители MOD делать, главное чтобы младший бит остатка был равен единице (нечётное число).
Никаких условий не надо- это обычный алгоритм деления, только на фиксированное число и с игнорированием частного. Делитель должен быть выровнен по левому краю.

Kakos_nonos
06.05.2014, 20:59
А есть быстрый алгоритм деления числа (байта) на 3? Желательно без таблиц.

alone
06.05.2014, 22:28
Умножить на 85 (%1010101) и сдвинуть на 8 бит.
;l=число
ld h,0
ld d,h,e,l
add hl,hl ;*2
add hl,hl ;*4
add hl,de ;*5
add hl,hl ;*10
add hl,hl ;*20
add hl,de ;*21
add hl,hl ;*42
add hl,hl ;*84
add hl,de ;*85
;h=результат

Reobne
08.05.2014, 11:14
Умножить на 85 (%1010101) и сдвинуть на 8 бит.
Теория правильная, но на практике, если этой программой 3 разделить на 3 получится 0. :(
Если аргумент меньше 128 то можно так (умножая на 86):

; аргумент А, результат H
rlca ;4 (98 тактов)
ld l,a ;4
ld h,0 ;7
rlca ;4
rlca ;4
rlca ;4
ld e,a ;4
and 7 ;7
ld d,a ;4
xor e ;4
ld e,a ;4
add hl,de ;11
ex de,hl ;4
add hl,de ;11
add hl,hl ;11
add hl,de ;11

Если аргумент меньше 255 то можно так (предварительный инкремент):


; аргумент А, результат H
inc a ;4 (107 тактов)
ld l,a ;4
ld h,0 ;7
rrca ;4
rrca ;4
rrca ;4
rrca ;4
ld e,a ;4
and 15 ;7
ld d,a ;4
xor e ;4
ld e,a ;4
add hl,de ;11
ld d,h ;4
ld e,l ;4
add hl,de ;11
add hl,hl ;11
add hl,de ;11

denpopov
16.12.2014, 16:41
http://z80-heaven.wikidot.com/math#toc35

Barmaley_m
18.12.2014, 17:07
Теория правильная, но на практике, если этой программой 3 разделить на 3 получится 0. :(
3*85/256 = 0.99609...
Если округлить до ближайшего целого - то получится правильный ответ, 1.

Например, если у нас в HL - результат от умножения на 85, то:


LD A,H
RL L
ADC A,0

Округлит результат.

---------- Post added at 16:07 ---------- Previous post was at 15:59 ----------

Только что проверил. Округление - это хорошо, но в деле нахождения остатка помогает плохо. Неверное частное без округления при умножении на 85 и делении на 256 получается только для тех чисел, которые делятся на 3 нацело. Но этот случай легко предусмотреть. Например, находим частное q = i*85/256 (округляем в меньшую сторону). Умножаем частное на 3, вычитаем из делимого. Получаем остаток, который будет равен 3 (а не 0) в случае, если исходное число делится на 3 нацело. Просто проверяем, что если вычисленный остаток равен 3 - то обнуляем его, и все.