· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Наноупражнение: принадлежность последовательности

. 1 . 2 . 3 . >>

Посл.отвђт Сообщенiе


Дата: Июл 1, 2004 00:14:40 · Поправил: _DEN_

Скажем, в eax находится число. Как самым коротким способом определить, является ли это число выделенным из последовательности:

0
~ 1 ~
~ 2 ~
3
4
5
6
~ 7 ~
~ 8 ~
9
10
11
12
~ 13 ~
~ 14 ~
15
16
...
И так далее...


Дата: Июл 1, 2004 00:44:48

Я могу поинтересоваться - а что это за последовательность? Для чего она нужна? Любопытно :)


Дата: Июл 1, 2004 01:09:46 · Поправил: _DEN_

Да вот пишу сейчас 4k Intro для Assembly'04. В данный момент мучаю генератор шестеренок с заданным количеством зубьев, косой передачей, ну и... еще много варьируемых параметров. Эта последовательность - значения счетчика при обходе вершин по часовой стрелке, при которой надо увеличивать радиус, чтобы визуально получились зубья. Хотелось бы покороче, потому как 4k Intro это номинация, в которой легко можно попасть в "историю одного байта" :-)


Дата: Июл 1, 2004 01:12:06 · Поправил: Funbit

самым коротким наверное
test byte ptr [offset table][eax], 1
jnz @MATCHED
где table db 0,1,1,0,0,0,0,1,1,0,0;.. ну и т.п.
если ресурсы не жалко конечно :)

edited: после предыдущего поста этот потерял свой смысл :)


Дата: Июл 1, 2004 01:46:53 · Поправил: _DEN_

..DEC...BIN........PARITY

....0 - 00000000 - 1
....1 - 00000001 - 0
....2 - 00000010 - 0
....3 - 00000011 - 1
....4 - 00000100 - 0
....5 - 00000101 - 1
....6 - 00000110 - 1
....7 - 00000111 - 0
....8 - 00001000 - 0
....9 - 00001001 - 1
...10 - 00001010 - 1
...11 - 00001011 - 0
...12 - 00001100 - 1
...13 - 00001101 - 0
...14 - 00001110 - 0
...15 - 00001111 - 1
...16 - 00010000 - 0
...17 - 00010001 - 1
...18 - 00010010 - 1
...19 - 00010011 - 0
...20 - 00010100 - 1
...21 - 00010101 - 0
...22 - 00010110 - 0
...23 - 00010111 - 1
...24 - 00011000 - 1
...25 - 00011001 - 0
...26 - 00011010 - 0
...27 - 00011011 - 1
...28 - 00011100 - 0
...29 - 00011101 - 1
...30 - 00011110 - 1
...31 - 00011111 - 0
...32 - 00100000 - 0
...33 - 00100001 - 1
...34 - 00100010 - 1
...35 - 00100011 - 0
...36 - 00100100 - 1
...37 - 00100101 - 0
...38 - 00100110 - 0
...39 - 00100111 - 1
...40 - 00101000 - 1
...41 - 00101001 - 0
...42 - 00101010 - 0
...43 - 00101011 - 1
...44 - 00101100 - 0
...45 - 00101101 - 1
...46 - 00101110 - 1
...47 - 00101111 - 0
...48 - 00110000 - 1
...49 - 00110001 - 0
...50 - 00110010 - 0
...51 - 00110011 - 1
...52 - 00110100 - 0
...53 - 00110101 - 1
...54 - 00110110 - 1
...55 - 00110111 - 0
...56 - 00111000 - 0
...57 - 00111001 - 1
...58 - 00111010 - 1
...59 - 00111011 - 0
...60 - 00111100 - 1
...61 - 00111101 - 0
...62 - 00111110 - 0
...63 - 00111111 - 1
...64 - 01000000 - 0


Вот они, "Игры разума" :-)
Где же ты, Морфиус, вечно тебя нет рядом когда ты так нужен... :-)


Дата: Июл 1, 2004 01:51:41

_DEN_
тоже уже 20 минут смотрю на такую же таблицу :)

а какой вариант сейчас имеется ?
пока кроме ((eax-1)%6<2) ничего не нашел...


Дата: Июл 1, 2004 02:03:45

Funbit
Да и у меня тоже самое... Эта шестерка как кол в задницу :) Жалко, что LEA в обратную сторону не работает...

Попробую вооружиться циклическими сдвигами...


Дата: Июл 1, 2004 02:34:06

Да... Что-то не получается у меня увязать делимость на 3 (6) с логическими операциями... Ладно пусть пока через DIV:

push eax
dec eax
mov edx,6
div edx
cmp edx,2
pop eax
jb __MACHED


Через DIV короче можно?
Да, на содержимое edx пофигу - я им стек выравниваю при работе с FPU.


Дата: Июл 1, 2004 06:46:50 · Поправил: Black_mirror

А какое максимальное значение может принимать число в eax?

Если eax<256*6, то проверку можно сделать так:
  push eax
  dec eax
  aam 6
  cmp al,2
  pop eax
  jb bigradius


Дата: Июл 1, 2004 11:10:23 · Поправил: RobinFood

_DEN_
Что-то не получается у меня увязать делимость на 3 (6) с логическими операциями...

Увязать-то можно, но через div получится короче.
Число делится на 6 (в любой системе счисления) тогда и только тогда, когда оно делится и на 2, и на 3.

Число делится на 3 в системе с основанием вида 3n-1 тогда и только тогда, когда разность
суммы цифр числа, стоящих на четных местах, и суммы цифр числа, стоящих на нечетных местах, делится 3.

Навскидку могу предложить такой длинный и неоптимизированный способ проверки делимости на 3:
mov ecx, eax
_l0:
mov edx, ecx
xor ecx, ecx
xor edx, AAAAAAAA
_l1:
shr edx,1
jnc _l2
inc ecx
_l2:
jnz _l1
mov edx, eax
xor edx, 55555555
_l3:
shr edx,1
jnc _l4
dec ecx
jnz _l3
test ecx,80000000
jz _l5
neg ecx
_l5:
cmp ecx,2
ja _l0
test ecx,ecx
jz _yes
_no:


Можно попробовать другой вариант: самому "проверить", делится ли число на 3. Принцип такой: если число делится на 2, делим его на 2, иначе отнимаем 3. И так до тех пор, пока не получим либо 0, либо 1. Примерно так:
mov edx,eax
_l0:
test edx,edx
jz _yes
cmp edx, 1
jz _no
test edx,1
jnz _l1
shr edx,1
jmps _l0
_l1:
sub edx,3
jmps _l0 


Можешь попытаься соптимизировать то или другое... но, по-моему, вариант с div-ом самый короткий.

ALL
Что-то я торможу. Как проще всего получить модуль числа?


Дата: Июл 1, 2004 11:28:49

Однако у меня в первом примере глюк:
почему-то я был уверен, что inc/dec, в отличие от add/sub, не меняют ZF.

Исправленный вариант:
mov ecx, eax
_l0:
mov edx, ecx
xor ecx, ecx
xor edx, AAAAAAAA
_l1:
shr edx,1
adc ecx,0
test edx,edx
jnz _l1
mov edx, eax
xor edx, 55555555
_l2:
shr edx,1
sbb ecx,0
test edx,edx
jnz _l2
test ecx,80000000
jz _l3
neg ecx
_l3:
cmp ecx,2
ja _l0
test ecx,ecx
jz _yes
_no:


Кстати, может количество битов числа тоже можно считать как-то проще?


Дата: Июл 1, 2004 11:40:24

Funbit
самым коротким наверное
test byte ptr [offset table][eax], 1

Зачем байты то, можно битовую строку.
И проверять бит по индексу.
См. программу bt.


Дата: Июл 1, 2004 16:24:54

Black_mirror
Да, твой вариант короче. С коротким переходом 9 байт получается.

eax будет меньше чем 6*n, где n - количество зубьев в шестеренке. Так что я думаю за 6*256 точно не вылезит :-)


Дата: Июл 1, 2004 17:31:22

_DEN_
Возможно что переход можно будет на fcmovb заменить. Жаль только что fcmovcc с памятью не работает.


Дата: Июл 1, 2004 18:05:34

Black_mirror
Кстати, не возникнет ли легкого фэйка когда eax равно нулю?

Да, conditional mov-ы очень длинные, переходы будут все же короче.

. 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.087