|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Сен 15, 2003 04:37:56 Сколько нужно инструкций чтобы проверить что число является степенью двух? |
|
|
Дата: Сен 15, 2003 04:49:22 Должна быть только одна единица. Думаю так: ; eax = input xor ecx,ecx next: test eax,eax jz done shr eax,1 adc ecx,0 jmp next done: cmp ecx,1 je YES jne NO |
|
|
Дата: Сен 15, 2003 05:12:44 :) lea edx,[eax-1] test eax,edx je @powerof2 |
|
|
Дата: Сен 15, 2003 05:22:44 · Поправил: Black_mirror The Svin lea edx,[eax-1] test eax,edx Итого 5 байт. Но можно сделать за 4 байта при том же количестве инструкций 8) All А если это float? |
|
|
Дата: Сен 15, 2003 05:49:40 Не испортив не сделаешь. |
|
|
Дата: Сен 15, 2003 06:58:05 А если это float? Дык это больше о матемачихе :) Что такое формат Float? - представление в виде мантиссы и экспоненты (двоичной) Что такое экспонента? - степень двойки на которую умножается мантисса. Какое число должно быть в экспоненте чтобы при умножении на степень двойки получилась степень двойки - классически - 1.0 - т.е. единица. Первая единица в формате FPU опускается. Но float разной длины - разнятся и биты выделенные под мантису (имеется ввиду индексы) поэтому нет универсального способа выделения мантисы. А так - если там 0 - степень двойки. |
|
|
Дата: Сен 15, 2003 08:31:27 super code (lea -1, test) |
|
|
Дата: Сен 15, 2003 11:36:07 тут еще зависит от того, что дальше будет. Как правило, это вычисления какие-нибудь, но можно и так: rcr eax, 1 jc @@odd ; even code here adc eax, eax @@odd: adc eax, eax |
|
|
Дата: Сен 15, 2003 14:55:32 The Svin поэтому нет универсального способа выделения мантисы .data some_float dd 128.0 .code fld some_float fxtract после этого в st(0) - мантисса в st(1) - порядок ==================== формат чисел с плавающей точкой: для float (4 bytes) имеем: sign (1 bit [31]) exp (8 bits [30 - 23]) fraction (23 bits [22 - 0]) для double (8 bytes): sign (1 bit [63]) exp (11 bits [62 - 52]) fraction (51 bits [50 - 0]) для extended (10 bytes): sign (1 bit [79]) exp (15 bits [78 - 63]) fraction (62 bits [61 - 0]) можно конечно произвести анализ мантиссы на 0, но стоит учесть особые виды чисел [0, -0, -inf, +inf, NaNs и денормализованые числа) |
|
|
Дата: Сен 16, 2003 17:58:11 lea edx,[eax-1] test eax,edx Отладив этот код :) у меня получилось: ;4 инструкции mov edx,1 bsf ecx,eax ;в ecx степень двойки shl edx,cl cmp edx,eax или ;3 инструкции bsf ecx,eax shr eax,cl cmp eax,1 ...чтобы учесть eax=0 |
|
|
Дата: Сен 16, 2003 20:37:03 Хм... Люди ещё могут подумать что мой код вдохновил тебя на bsf :) Чур меня чур - изыди :))) Не получилось у тебя ни 3и ни 4е - дважды отсутсвует проверочный tttn - jcc или setcc или movcc. Ты в курсе что если в eax 0 то ecx вообще не изменится? И тебе нужно делать проверку на ZF после BSF? Затем вторая опущеная проверка уже после сдвига. Итого 5 или 6 инструкций а не 3 и 4е. При этом использование медленной bsf. Просто добавь к моему коду если нужна проверка на 0 (хотя математики до сих пор не пришли к окончательному мнению не является ли 0 степенью n в минус бесконечности). test eax,eax je Zcode Остальное оставь. Код будет работать в 2а раза быстрее и портится будет только один регистр при этом. |
|
|
Дата: Сен 16, 2003 21:20:29 · Поправил: The Svin super code (lea -1, test) Вообще особено хитрого в коде нет, только объяснение лежит не в поле ассемблера а свойствах позиционной системы. Можем посмотреть и в десятичной 1000 - 1 = 0999 21000 - 1 = 20999 В своё время у меня пацан додумался самостоятельно до этого приёма, правда без lea - он её не знал. Ему помог не ассемблер а знание позиционных систем в частности бинарные паттерны. Я думаю через несколько секунд, все кто считал это очень хитрым увидят, что это очень просто. Сначала пара простейших патенов: 10..(х нулей в том числе и 0 нулей).. = 10^x если число в двоичной 2^x, в десятичной 10^x Для двоичной 11..(x единиц).. = 2^x -1. Т.е. если мы поставим их 2^x и 2^x - 1 друг под другом, бит под битом мы увидим что 1 оказывается под нулём. Теперь в чём разница между числом степенью двойки и не степенью? Число не степень двойки представляет собой в бинарном виде сумму нескольких степеней двойки. например 1010 = 1000 + 10 И важно обратить внимание что среди этих нескольких степеней есть наименьшая среди них. например в 1010=1000 + 10 наименьшая 10. Вычитание единицы изменяет наименьшуюстепень и никак не изменяет остальных. т.е. 1010 - 1 = 1000 + (10-01)= 1000+1=1001 Согласно описанию выше рисунков эта наименьшая степень обнулиться при она and (она - 1) т.е. в примере: 1010 and 1001=1000 Но на другие (старшие) степени (биты) это не повлияет x-1 изменила только наименьшую степень-слогаемое бинарного числа, и 1000 остался в нашем примере неизменным. Поэтому 1010 and 1001 не дал ноль - этому не дал произойти оставшийся на месте третий бит 1010 and 1001 Но это произойдёт если у нас в слогаемых-степенях числа лишь одна степень двойки и никаких "выше" её степеней больше нет. Например 1000 (2^3) и 0111(2^3 -1) = 0000 Особый случай когда наименьшей степенью является нулевая (0001) также не портит этого правила в этом случае дальше нет бит а вычитание в 2^x -1 старший бит 2^x всегда превращается в 0. Надеюсь сейчас всё уже кажется просто банально. Вот. Об всех этих фокусах с использованием свойств позиционной системы в низкоуровневом программировании пишется книжеца для детей младшего и старшего возраста. |
|
|
Дата: Сен 16, 2003 22:45:51 · Поправил: Fixer |
|
|
Дата: Сен 16, 2003 22:46:16 The Svin Да я в свое время делал это примерно так mov eax, digit not eax inc eax and eax, digit cmp eax, digit je @powerof2 Позаимствовал у Кнута ("Исскуство программирования"). Но твой способ лучше. |
|
|
Дата: Сен 17, 2003 13:54:05 Задача была такая: Сколько нужно инструкций чтобы проверить что число является степенью двух? Ограничений на число тактов или регистров нет :) ; для eax=0 ; для eax!=0 bsf ecx,eax ; ecx=? ; ecx=n shr eax,cl ; eax=0 ; dec eax ; ZF=0 ; ZF=1, если eax=2^n, иначе ZF=0 ;проверка закончена ;здесь нужно использовать setcc/cmovcc/jcc Просто добавь к моему коду test eax,eax je Zcode А если мне не нужны пржки и достаточно одного cmovcc или setcc??? Еще. Регистр ecx не портится, в нем возвращается N :) |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.093 |