Посчитать количество бинарных строк в dword Под бинарной строкой понимается непрерывные единички или нули. Пример в DWORD = FFFFFFFFh - одна бинарная строка столько же в 00000000h В 0000FFFF таких строк две столько же в 80000000h а вот в 10000000h - их 3
может можно и проще, но лень и позднее время мешают: Код (Text): mov eax, 10000000h ; sample value mov edx, 1 mov ebx, eax and ebx, 1 mov ecx, 32 xor edi, edi @@: shr eax, 1 adc edi, 0 xor ebx, edi add edx, ebx mov ebx, edi xor edi, edi dec ecx jnz @B mov eax, edx
Первые крупные мозги подключились. Это радует. Один из вариантов "ответного" кода Код (Text): SignalCountsDword proc DwIn mov eax,DwIn sub ecx,ecx test eax,eax jne @F lea eax,[ecx][1] @r: ret @@: lea edx,[eax-1] add ecx,1 or eax,edx lea edx,[eax+1] and eax,edx jne @B mov eax,DwIn shr eax,1 sbb edx,edx shr eax,30 sbb eax,eax lea eax,[eax][edx][1] lea eax,[eax][ecx*2] jmp @r SignalCountsDword endp
Да, мой код очень легко адаптируется для непрерывного массива (задача №7(?)), а не только одного значения
Такой вариант... Вход - EDX, выход - EBX (можно любые написать). Код (Text): xor ebx, ebx shr edx, 1 salc mov ah, al mov ecx, 31 ;( l1: shr edx, 1 salc cmp al, ah jz l2 inc ebx mov ah, al l2: loop l1
Код (Text): mov eax,num mov ecx,eax sar ecx,1 xor ecx,eax;число строк=числу единичных бит +1 sub eax,eax .l0: inc eax .l1: add ecx,ecx ja .l1 jc .l0
Код (Text): mov eax,DwIn xor ecx,ecx xor edx,edx shr eax,1 sbb ebx,ebx mov cl,31 inc edx xor eax,ebx @MLoop: shr eax,1 sbb ebx,ebx adc dl,dh xor eax,ebx loop @MLoop xchg eax,edx ; EAX - результат
Код (Text): mov eax, inDWORD mov ebx, eax not eax ror ebx, 1 xor eax, ebx xor edx, edx mov ecx, 32 inc edx M0: shr eax, 1 jc M1 inc edx M1: loop M0 mov Result, edx
С подсчетом бит по Уоррену Код (Text): mov eax,dword mov ecx,eax sar ecx,1 xor eax,ecx mov ecx,eax shr ecx,1 and ecx,55555555h sub eax,ecx mov edx,eax and edx,33333333h shr eax,2 and eax,33333333h add edx,eax mov ecx,edx shr ecx,4 add ecx,edx and ecx,0F0F0F0Fh mov edx,ecx shr edx,8 add edx,ecx mov eax,edx shr eax,16 lea eax,[eax+edx+1] and eax,03Fh
bogrus Идея со сдвигом и последующим исключением хороша, но имеет недостаток! Если последний бит - это "битовая строка" длиной в 1 бит, то он выпадает и результат становится неверным. Пример: 00000002 В моём случае, ror также не спасает, так как если первый и последний биты dword не равны, а последняя битовая строка длиной более 1 бита, то получается лишняя битовая строка. Пример: 00000003 Так что - надо думать :\ Пока что самое оптимальное решение у _BC_
? Это как это низкоуровневый программист Tupo инетересно оценивает алгоритмы? В числе типа FFF0FFFF0 мой алгоритм вычисляет количество строк всего за два цикла. Кто-то анализировал как он работает? Он выполняется за <= x\2 циклов. Где x - количество строк (не бит, - строк). bogrus А биты то нам зачем считать? Нам строки посчитать нужно. Уоррена мы с Яном любим. Но по сравнению с нашей эльфийской книжкой "Кольца и стрелы" - его труд детский
У Black_mirror'a лучше Я даже не стал посылать улучшенный вариант, а сразу переключился на задачу №4. Вот там мой вариант элегантен как рояль (по крайней мере по размеру)
Нужно постараться избежать циклов в алгоритмах где количество циклов = количеству бит во входных данных.
The Svin Так смысл, выделить границы битовых строк, а потом посчитать кол-во границ (еденичных битов) Tupo 0x00000002=00000000000000000000000000000010b=3 строки 0x00000003=00000000000000000000000000000011b=2 строки Ты не согласен, с результатом? Может есть ещё примеры? Имхо, если нужна скорость, я бы использовал подсчет по Уоррену (это примерно в десять раз быстрее большинства предложенных циклов, даже в 1,5 раза быстрее чем 2 прохода цикла The Svin при числе 0FFF0FFF0h), конечно при условии, что это работает правильно на всех числах, я позже обязательно перепроверю, пусть появится чуть больше свободного времени
bogrus Конечно не согласен А в этом примере: 55555555h сколько строк? 33? The Svin Производительность! Но твой вариант - не смотрел, каюсь
Ладно, проехали. Но всё же под производительностью можно разное понимать - эмпирику по тестам, оценку циклов и тп. Кстати я дал не самый быстрый из возможных. Только чтоб подтолкнуть в направлении. Мне интересней Ваши идеи - свои я и так знаю
Tupo Где 33? Код (Text): MOV EAX,55555555 ; EAX=55555555 ; 1010101010101010101010101010101b MOV ECX,EAX ; ECX=55555555 SAR ECX,1 ; FL=CP, ECX=2AAAAAAA ; 0101010101010101010101010101010b XOR EAX,ECX ; FL=P, EAX=7FFFFFFF ; 1111111111111111111111111111111b MOV ECX,EAX ; ECX=7FFFFFFF SHR ECX,1 ; FL=CP, ECX=3FFFFFFF AND ECX,55555555 ; FL=P, ECX=15555555 SUB EAX,ECX ; EAX=6AAAAAAA MOV EDX,EAX ; EDX=6AAAAAAA AND EDX,33333333 ; EDX=22222222 SHR EAX,2 ; FL=CP, EAX=1AAAAAAA AND EAX,33333333 ; FL=P, EAX=12222222 ADD EDX,EAX ; EDX=34444444 MOV ECX,EDX ; ECX=34444444 SHR ECX,4 ; ECX=03444444 ADD ECX,EDX ; ECX=37888888 AND ECX,0F0F0F0F ; FL=0, ECX=07080808 MOV EDX,ECX ; EDX=07080808 SHR EDX,8 ; EDX=00070808 ADD EDX,ECX ; FL=A, EDX=070F1010 MOV EAX,EDX ; EAX=070F1010 SHR EAX,10 ; FL=PA, EAX=0000070F LEA EAX,[EAX+EDX+1] ; EAX=070F1720 AND EAX,3F ; FL=0, EAX=00000020 ; 32d
bogrus Еще раз но медленнее... 00000002 = 00000000000000000000000000000010 = 3 строки результат сдвига + xor = ...011 - 2 единицы, значит количество строк = количество "1" + 1. Так? Так! 00000003 = 00000000000000000000000000000011 = 2 строки результат сдвига + xor = ...010 - 1 единица, значит количество строк = количество "1" + 1. Так? Так! 55555555 = 1010101010101010101010101010101 результат сдвига + xor = 11111111111111111111111111111111 - 32 единицы, и как же количество строк = 32 получилось? Я что-то не пойму :\