Поиск:

Ответ в темуСоздание новой темы Создание опроса
> биты и байты №2, задачка на сообразительность ;) 
:(
    Опции темы
PILOT
Дата 2.10.2002, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


производство
****


Профиль
Группа: Модератор
Сообщений: 2724
Регистрация: 4.4.2002
Где: москва

Репутация: нет
Всего: 54



В Асс, твой БАЙТ (извини, но 8 бит)
Есть одна инструкция:
SBRC Acc,7;     :) это определение 1-го (старшего) бита (как видно он 7-ой)
это AVR_Asm...
а можно так:
LsL Acc;   сдвигаю влево байт и смотрю на перенос, есть значит 1, нет 0.
BrCS  Label1; и если 1 то на метку Label1
Nop; если 0, то ничего не делаем...

Так же сдвигами можно определить кол-во (сдвиги есть везде, Pascal, C++, ASM) 1-ц и нулей, причем в ЛЮБОМ "Байте" даже в ВОРДЕ :)))
Пусть этот ВОРД будет даже 2-х битным или 43-х битным,
знай себе двигай влево и считай выползающие единички.
А еще можно сделать так:
если БАЙТ(8-ми битный:)) > 128 то первый бит стоит, и наоборот (unsigned).
А можно так:
(X and $80) > 0, то 7-ой бит стоит, и наоборот если = 0, то там ноль.
теперь сдвигаем $80 вправо, т.е. получаем $40
и опять:
(X and $40) > 0, то 6-ой бит стоит, и наоборот если = 0, то там ноль.

СУВ.
ЗЫ.
Девушка на экзамене по информатике. Преподаватель:
- Сколько бит в байте???
- А можно выйти?
- Можно... недолго!
Девушка быстро совещается с кем-то первым попавшимся за дверью, входит уже счастливая:
- Сколько бит в байте??????
- Восемь!...
Препод облегченно вздыхает, два часа у нее уже принимает, начитает рисовать удовл., и врдуг:
- ...а в каждом четвертом 9!!!!!!...
- !!?!?!?!?!?
- Каждый четвертый високосный!!!!!


--------------------
тут могла быть Ваша реклама...
PM MAIL WWW ICQ   Вверх
Kesh
Дата 2.10.2002, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2488
Регистрация: 31.7.2002
Где: Германия, Saarbrü cken

Репутация: нет
Всего: 54



Цитата
э... мда... про наболевшее. про 8 бит.

А как вообще можно считать количество нулей, если не определена 'длина' числа?..

Можно я немного пофилософствую?.. Нет... Ну тогда дальше не читай... :0)

Что такое по своей сути представляет подсчет нулей?... Это цикл, как ни крути, как ни пиши ты его, хоть в одну строку, хоть в восемь, но это цикл... Извините, но меня учили, что всякий алгоритм есть следование, ветвление и цикл... все остальное - разновидности... Так что если без цикла, то остается следование и ветвление... Ну конечно можно сказать что восемь строк кода - это следование, но по сути это развернутый цикл... Я думаю, что тут уместнее был бы вопрос о том не сколько нулей, а есть ли они вообще... А тогда надо просто сравнить число с 255 (по-моему оно соответствует числу b11111111), но здесь мы опять же зацикливаемся на 8-ми битах... :0(

P.S. Очень надеюсь, что я не прав, и чей то гениальный алгоритм докажет обратное... :0)

P.S.(for Vit): Я вот тута как-то постоянно критикую твои алгоритмы, прошу прощения... Просто обычно твои отзывы я читаю внимательнее, чем другие... Так что не воспринимай это как нападки - это самая наглая лесть... :0)


--------------------
user posted image
PM MAIL WWW ICQ Skype   Вверх
Vit
Дата 2.10.2002, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: нет
Всего: 207



Цитата(kesh @ 01.10.2002, 17:49)
P.S.(for Vit): Я вот тута как-то постоянно критикую твои алгоритмы, прошу прощения... Просто обычно твои отзывы я читаю внимательнее, чем другие... Так что не воспринимай это как нападки - это самая наглая лесть... :0)

А я тут причём! Я с тобой совершенно согласен, я именно это и сказал в своём ответе - что практически я вижу решение только через цикл. Впрочем я, к моему великому сожалению, алгоритмику в ВУЗе не изучал, и для меня это тёмная область...


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Chingachguk
Дата 2.10.2002, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 1
Всего: 18



Есть еще извратный вариант- с размножающимся кодом, и без всякого учета числа бит в байте !


Цитата

text segment byte
assume cs:text,ds:text
org 100h
begin:
 mov  al,134
 call Get_NBits
 add  Message+6,al
 mov  ah,09h
 mov  dx,offset Message
 int  21h
 ret
Get_NBits proc near
 xor  ah,ah
 xchg al,ah
@@Begin:
 shr  ah,1
 adc  al,0
 test ah,ah
 jnz  @@Next
 retn
@@Next:
 call @@GetOfs
@@GetOfs:
 pop  si
 sub  si,@@GetOfs-@@Begin
 mov  di,si
 add  di,offset @@End-offset @@Begin
 mov  cx,@@End-@@Begin
 push di
 rep  movsb
 retn
@@End:
 db   (@@End-@@Begin)*8 dup(?)
Get_NBits endp
Message db 'bits: 0','$'
text ends
end begin



--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
PILOT
Дата 4.10.2002, 05:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


производство
****


Профиль
Группа: Модератор
Сообщений: 2724
Регистрация: 4.4.2002
Где: москва

Репутация: нет
Всего: 54



Цитата(kesh @ 02.10.2002, 02:49)
А как вообще можно считать количество нулей, если не определена 'длина' числа?..

Мнда... если неизвестен формат числа, то нельзя рассуждать о его содержимом.
Я знаю что это число байт, я считаю в нем нули (единицы).
Ворд, тоже.
Но если я не знаю какая ширина и динна как же я площадь искать буду?

Самомодифицирующийся код, это хорошо, но ведь он разрастается в зав-ти от формата числа, т.е. он заранее известен.

СУВ.
ЗЫ. Я повторю то что я писал Вашему коллеге (будет проще):
Каждому символу соответствует число (0-255)
Каждое число может быть записано в разных системах счисления, в двоичной, например.
Число символов, которое устраивало всех (для набивания текста+простые таблицы) в текстовом режиме было около 190.
Т.к. компутер понимает двоичную систему и т.к. минимальное число близкое к 190 и являющееся степенью 2-х (двоичная система) есть 256, т.е. это 2 в степени 8.
мы пишем 0 в десятичной, это есть 00000000 в двоичной.
пишем 36 в десятичной,    это есть 00100100 в двоичной, почему так?
Номера бит (нулевой всегда младший, 7 старший:  т.е. любой отсчет идет с нуля):
7     6     5     4     3     2     1     0 - это байт, из 8-ми бит.
128  64   32    16   8     4     2     1 - это вес разрядов, так же как в десятичной системе десятки, 1000 100 10 1, где 9 это максимальный разряд, а тут максимальный разряд 1, т.е. сначала 0, потом 1, потом 10, потом 11 и т.д.
Т.е. перенос сразу после 1-цы, а в 10-чной системе после 9-ки.
Итак 01000100:
Как узнать что это за число в десятичном виде: просто берем и складываем веса разрядов. нулевой разряд = 0 , с ним нечего делать и первый 0, они пустышки, теперь 2-ий = 1. Ага 3-й это значит 4 (2^2=4), дальше опять нули, до 6-го разряда (справа налево разряды считаем), 6-ый разряд = 1, ага это 64, т.к. 2^6=64 (а в уме те 4 держим). Дальше по разрядам все нули.
Теперь складываем 64+4=66. 66 в десятичной системе есть 01000100.
Вот и все.


--------------------
тут могла быть Ваша реклама...
PM MAIL WWW ICQ   Вверх
cosmic
Дата 5.10.2002, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 28.9.2002

Репутация: нет
Всего: нет



PILOTIK, спасибо, если в двух темах похожие названия, то это не значит, что в них надо писать одинаковые вещи:)))
Цитата

А как вообще можно считать количество нулей, если не определена 'длина' числа?..

kesh, "подсчитать" - не всегда " = цикл". давай так, сколько нулей в числе 1, при том, что нам не известна его "длина"? правильно, фиг знает сколько. а сколько в нём единиц? правильно, всегда только одна. подумать. и речь наверно идёт о том, чтобы именно "вычислить", а не "подсчитать". спасибо тоже.

Chingachguk, я не говорю на ассемблере :( может эту фишку - с, прости господи, размножающимся кодом - можно как-нибудь пересказать по-русски или на Си (у тебя хорошо получается), пожАААААлуйста :) что же касается двух предыдущих... хм... ну, первый - это [Chingachguk 1] extended to int, а второй... что ж, зачисляю его в претенденты, хотя изящность, как ты сам верно указал, не самая сильная его сторона.
Цитата

Итого! Из всех путей авторы топика имеют ввиду очевидно 2.б и я очень сомневаюсь, чтобы можно было решить проблему этим путём.

Vit, "авторы топика" действительно надеялись... тьфу ты... я надеялся услышать эту формулу. поскольку её никто не знает (или знает, да помалкивает :), то вероятно топик надо заморозить, до тех времён, пока наука информатика не шагнёт ещё на 7 миль вперёд и новый дейкстра не прославит себя для потомков изобретением сей формулы; я к этому времени наверно буду уже познавать все прелести реинкарнации...

ВНИМАНИЕ:

топик закрывается на фиг! всем сдать работы (кто ещё этого не сделал). "авторы топика" ещё подождут комментариев Chingachguk'а, а потом уже состоится самый субъективный и несправедливый на свете суд :)
PM MAIL   Вверх
Chingachguk
Дата 6.10.2002, 06:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 1
Всего: 18



[QUOTE]
Chingachguk, я не говорю на ассемблере :( может эту фишку - с, прости
господи, размножающимся кодом - можно как-нибудь пересказать по-русски
или на Си (у тебя хорошо получается), пожАААААлуйста :) что же касается
двух предыдущих... хм... ну, первый - это [Chingachguk 1] extended to
int, а второй... что ж, зачисляю его в претенденты, хотя изящность, как
ты сам верно указал, не самая сильная его сторона.
[QUOTE]

Насчет размножающегося кода: На СИ мне такое не представляется сделать возможным ;) правда, есть какие-то потоки в VC ;) Ну да ладно:

; Процедура получает в регистре al байт для подсчета в нем бит
Get_NBits proc near
; Очищаем ah, ah будет 0
xor  ah,ah
; Обменивем регистры al и ah, al=ah, ah=al
xchg al,ah
; al теперь у нас СУММАТОР, ah содержит переданный байт
; @@Begin - Начало самокопирующегося кода
@@Begin:
; shr ah,1 <=> ah>>=1 На СИ
shr  ah,1
; Добавляем ушедший бит к сумматору (al)
; Во всех языках бит(нулевой) уходит в никуда, только на ассемблере
; мы его помним ;)))
adc  al,0
; Если ah не равно нулю, переходим на @@Next
; (if (ah != 0) goto @@Next else return(al);)
test ah,ah
jnz  @@Next
; Иначе возвращаемся, результат вернем в регистре al
retn
@@Next:
; Получаем текущее смещение кода
; Ведь команда call записывается как call(опкод)0003
; Те процессор вызовет код ВСЕГДА НА ТРИ БАЙТА ВПЕРЕД
call @@GetOfs
@@GetOfs:
; Выталкиваем из стека адрес возврата,
; Фактически - смещение метки @@GetOfs в регистр si
pop  si
; Указываем на метку @@Begin, вычитая длину кода
; между метками
sub  si,@@GetOfs-@@Begin
; Вычисляем адрес метки @@End в регистре di
mov  di,si
add  di,offset @@End-offset @@Begin
; В регистр cx кладем число байт между метками @@Begin и @@End
; Фактически - длину самокопирующегося кода
mov  cx,@@End-@@Begin
; Запоминаем в стеке адрес метки @@End
push di
; Копируем размножающуюся часть вперед за @@End
rep  movsb
; Переходим на скопированный код
; (В 8086 делать push di ... retn необязательно,
; но в 386+ нужно сбросить предвыборку команд - конвеерер CPU)
retn
@@End:
; Резервируем место для максимум CHAR_BIT
; Копирований кода
db   (@@End-@@Begin)*CHAR_BIT dup(?)
Get_NBits endp

Фактически, что мы делаем ? Добавляем очередной бит к сумматору, если
параметр все еще не ноль, копируем свой код и передаем на него управление, он делает то же самое еще раз и т.д.
Если хочешь посмотреть это "вживую", скомпили мою прогу:

masm <имя файла>.asm
tlink <имя_файла>.obj /t

И посмотри в отладчике, например td.exe. Только жми на F7, а не на F8 - trace step !

Это решение - скорее прикол. Использование твоей неточной формулировки:
это цикл ? - нет, где же постоянное начало его и конец ? Это рекурсия ?
Тоже нет ;)))

Насчет # - директив компиллера - ты смотри, как еще можно:

#if  CHAR_BIT equ 1
res=b;
#elseif CHAR_BIT equ 2
res=b+(b>>1);
#elseif CHAR_BIT equ 4
res=(b&0x05)+((b&0x0A)>>1);
res=(b&0x03)+((b&0x0C)>>2);
...

Любопытно также (это мое "заднее слово") использование синусов:

Нулевой бит = sin^2(ПИ*x/2);
Первый бит = (1-sin^2(ПИ*x/2))*sin^2(ПИ*x/4)+sin^2(ПИ*x/2)*sin^2(ПИ*(x-1)/4);
...
(Раскручиваем условие:
  if (bit0 == 0)
    bit1 = sin(ПИ*b/2);
  else
    bit1 = sin(ПИ*(b-1)/2); )
Предел, как ты уже говорил - через ln(b)/ln(2), ln - основание e;
Ну и так далее... Упрстить такое выражение я не смог ;(, правда и не
очень старался ;)))

Вообще, по моему мнению, не существует функции(математич.), которая сможет сделать такой рез-т, ибо ты видел график этой функции ? :) Мне кажется, что в ряд ее разложить нельзя - она там не непрерывная или что-то в этом роде - следовательно, математическая форма невозможна (?) - ну это вроде как дельта-функцию в ряд разложить ж)))


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Alex101
Дата 7.10.2002, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 891
Регистрация: 8.4.2002
Где: Москва

Репутация: 1
Всего: 10



А так не пойдет?:
Код

const char *s[9]={
"нет нулей","нулевой","первый","второй",третий",
"четвертый","пятый","шестой","седьмой"
};
unsigned char a,k,n;
scanf("%d",&a);

k=8-((((a>>7))&1)+(((a>>6))&1)+(((a>>5))&1)+(((a>>4))&1)+(((a>>3))&1)+(((a>>2))&1)+(((a>>1))&1)+((a)&1));
n=((((a>>7)&1)^1)&1)*8+((((a>>6)&1)^1)&1)*(((((a>>7)&1)^1)&1)^1)*7+((((a>>5)&1)^1)&1)*(((((a>>7)&1)^1)&1)^1)*(((((a>>6)&1)^1)&1)^1)*6+((((a>>4)&1)^1)&1)*(((((a>>7)&1)^1)&1)^1)*(((((a>>6)&1)^1)&1)^1)*(((((a>>5)&1)^1)&1)^1)*5+((((a>>3)&1)^1)&1)*(((((a>>7)&1)^1)&1)^1)*(((((a>>6)&1)^1)&1)^1)*(((((a>>5)&1)^1)&1)^1)*(((((a>>4)&1)^1)&1)^1)*4+((((a>>2)&1)^1)&1)*(((((a>>7)&1)^1)&1)^1)*(((((a>>6)&1)^1)&1)^1)*(((((a>>5)&1)^1)&1)^1)*(((((a>>4)&1)^1)&1)^1)*(((((a>>3)&1)^1)&1)^1)*3+((((a>>1)&1)^1)&1)*(((((a>>7)&1)^1)&1)^1)*(((((a>>6)&1)^1)&1)^1)*(((((a>>5)&1)^1)&1)^1)*(((((a>>4)&1)^1)&1)^1)*(((((a>>3)&1)^1)&1)^1)*(((((a>>2)&1)^1)&1)^1)*2+(((a&1)^1)&1)*(((((a>>7)&1)^1)&1)^1)*(((((a>>6)&1)^1)&1)^1)*(((((a>>5)&1)^1)&1)^1)*(((((a>>4)&1)^1)&1)^1)*(((((a>>3)&1)^1)&1)^1)*(((((a>>2)&1)^1)&1)^1)*(((((a>>1)&1)^1)&1)^1)*1;

printf("%d\n",k);//кол-во нулевых бит
printf("%s\n",s[n]);//номер первого нулевого бита (от старшего)

ЗЫ
Тут много лишних скобок, но у меня компилер (VC++6.0) что-то без этих лишних глючит...
А так - не только без циклов но и без условий обойтись можно
ЗЗЫ
На асм уже легко будет переписать, ежели надо, то напишу.


--------------------
С уважением, А. Фролов.
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.3655 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.