Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Anonymous Гость
|
Добавлено: Чт Авг 01 2002 23:14 Заголовок сообщения: Помогите разобраться в битовой арифметике |
|
|
Люди, помогите. Не знаю для чего конкретно нужен сабж и где его часто употребляют. Как в этих всех циферках разобраться? Что за здвиги, зачем? Хорошо, скорость, а еще? Помогите, хочу разобраться, эта штука до меня не доходит. Может кто хорошие ссылки подкинет.
Спасибо. |
|
Вернуться к началу |
|
|
xorxor Гость
|
Добавлено: Пт Авг 02 2002 07:25 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Смотри на вещи шире: "Что это вообще за компьютеры такие, зачем ?"
А если хочешь конкретный ответ, спрашивай по пунктам |
|
Вернуться к началу |
|
|
Anonymous Гость
|
Добавлено: Пт Авг 02 2002 20:40 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Да, с цыферками я переборщил. Вопросы такие: 1. В каких, конкретно, приложениях используется битовая арифметика.
2. К примеру, знаю, что с помощью какой-то операции можно поделить целое,четное число, если можно так выразиться, это приведет к ускорению данного процесса. Но для чего остальные операторы? Как я узнаю какое десятичное число получится после инвертировании битов NOT(ом)? [Сдвиг влево, сдвиг вправо, как узнать что получится. Какого результата ожидать?]
3. Но NOT это, видимо, один из самых легких примеров, хотя то же не понятно, а XOR, AND и т.п. Вопросы, пока, одинаковые. Возможно слишком обширные, но пока, увы, по-скольку я не могу понять простых, в этой области, вещей то и умные вопросы задавать не получится.
Спасибо за терпение |
|
Вернуться к началу |
|
|
Anonymous Гость
|
Добавлено: Пт Авг 02 2002 20:44 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Извиняюсь, конечно я узнаю какое число получится, если инвертирую NOTом, переведя из двоичной в десятичную, но как предвидеть результат, и чего ожидать? |
|
Вернуться к началу |
|
|
Adil Гость
|
Добавлено: Сб Авг 03 2002 15:05 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Тебе наверно надо понять, что такое вообще различные ситемы исчисления - десятичная, двоичная и т.д.
вот пусть мы имеем некотрое число, записанное в десятичной системе как "3421". Каждая цифра в этом числе занимает свою позицию, нумерация идет справа на лево c 0, и суть этой позиции (для десятичного числа!) это степении десятки: 3421 = 1*10^0+2*10^1+4*10^2+3*10^3 Для остальных систем то же самое, только степень по другому основанию (ну и количество цифр другое). Для двоичной: 101001b=1*2^0+0*2^1+0*2^2+1*2^3+0*2^4+1*2^5=41 Каждая позиция двочного (и только двоичного!) числа называется битом. Бинарные логические опрерации, т.е. операции над битами AND (&), or(|),XOR(^) и т.д., соответствуют логическим опрерациям (как в логике только 2 значения "истина-ложь", так и тут "1-0" 1-истина, 0-ложь), только бинарные производяться с битами в одинаковой позиции и бит-результат заноситься в этуже позицию.
Пример1: 1011b&1001b= |-------- результат ---------| бит3 бит2 бит1 бит0 = (1&1=1) (0&0=0) (1&0=0) (1&1=1) = 1001b
Пример2: 1011b|1001b= |-------- результат ---------| бит3 бит2 бит1 бит0 = (1|1=1) (0|0=0) (1|0=1) (1|1=1) = 1011b Пример3: 1011b^1001b= |-------- результат ---------| бит3 бит2 бит1 бит0 = (1^1=0) (0^0=0) (1^0=1) (1^1=0) = 10b Пример4: ~1011b= |-------- результат ---------| бит3 бит2 бит1 бит0 = (~1=0) (~0=1) (~1=0) (~1=0) = 100b
8 бит соответствуют 1 байту
В программировании очень широко используется 16-ричная система. Ее удобство - каждая цифра 16-ричного числа соответствует 4 цифрам двоичного числа (т.н. тетрада). 0x1AB2 = (0001)(1010)(1011)(0010) Т.о. 2 цифры 16-го числа соответствуют 1 байту
Сдвиговые опрерации. В десятичном исчислении: 37886*10=378860 - т.е., умножая, на десять мы сдвинули число на 1 цифру влево, заполнив появившееся место 0. В десятичном исчислении: 37886/10=3788 - т.е., деля на десять, мы сдвинули число на 1 цифру вправо, отбросив 0-вую цифру.
Сдвиговые операции |
|
Вернуться к началу |
|
|
Adil Гость
|
Добавлено: Сб Авг 03 2002 15:15 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Досылаю.
Сдвиговые операции |
|
Вернуться к началу |
|
|
Adil Гость
|
Добавлено: Сб Авг 03 2002 15:18 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Черт! Опять забыл, что на этом форуме кто-то угловые скобки не любит заменил на [ и ]
Сдвиговые операции [[ и ]] - то же самое, только относяться к двоичным числам, и "десяткой" у них "работает" двойка: (1011b)*2=10110b=1011b[[1 а "сотней" "работает" 4: (4=2*2 как 100=10*10) (1011b)*4=101100b=101100b[[2 (1011b)*8=1011000b=1011000b[.. если тебе надо поделить число, например, на 32, ты можешь просто написать a=235635]]5 (=235635/32)
Ну вот в принципе и все основное, что надо знать - дальше уж сам. Книг не советую -ни к чему, это лучше изучать методом научного тыка - пиши простенькие программки и смотри, что получается. Очень полезно - напиши сам функцию вывода числа в двоичном формате в строку: типа на входе 3575467, а на выходе строка "1101101000111010101011".
Удачи. |
|
Вернуться к началу |
|
|
Anonymous Гость
|
Добавлено: Сб Авг 03 2002 20:30 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Большое спасибо! Начинает проясняться. Если можно, еще пару вопросов. 1. Как из десятичной в двоичную, 16ти-ричную. 2. Как использовать 16ти-р. 3. В каких приложениях используются операции над битами. 4. Можно делить/умножать только на 2,4,8,16,32,64..? как поделить/умножить на 3,5, если можно. 5. Как я понял, сдвиги используются только для деления/умножения на 2,4,8,16,32 , єто так? 6. Нужно ли запоминать "таблицы результатов" операторов битовой арифметики, ели правильно выразился.Если "да" то может имеется способ как это лучше сделать?
Еще раз спасибо. |
|
Вернуться к началу |
|
|
Adil Гость
|
Добавлено: Вс Авг 04 2002 11:28 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
>Если можно, еще пару вопросов. >1. Как из десятичной в двоичную, 16ти-ричную. Смотря что ты имеешь ввиду. Если это переменная, то она в машине всегда храниться как двоичная.. - машина только такие и понимает. А само преобразование производиться компилятором автоматически: int a=10, b=0xA,c=012; (10рич)(16рич)(8рич) При переводе само число не меняеться. Меняется только вид представления. Поэтому есть смысл говорить о переводе из одной системы в другую только для строк, которыми представлено это число.
char* str10[0x100]="32156"; //в str10 10чная запись 32156 char* str16[0x100]; int a; //"считываем" число в переменную a sscanf(str10,"%d",&a); //здесь a=32156 или a=0x7D9C или //111110110011100b - это все одно и тоже. ssprintf(str16,"%x",a);//в str16 - 16чная запись числа 32156
strcpy(str16,"0x5567");//в str16 - 16чная запись числа 21863 sscanf(str16,"%x",&a); //здесь a=21863 или a=0x5567 или //101010101100111b - это все одно и тоже. ssprintf(str10,"%d",a);//в str10 10чная запись 21863
2. Как использовать 16ти-р. да так же, как и любые другие. Просто иногода удобнее видеть число в 16м виде, а иногда в 10ом. (именно видеть - само-то число не меняеться).
3. В каких приложениях используются операции над битами. Да скорее всего во всех - просто это внутри операторов. А если в явном виде, то вот идиотский пример. Пусть есть некоторое устройство у котрого есть 8 лампочек - каждая может гореть или не гореть. Чтобы описать состяние этих лампочек, можно ввести 8 переменых типа bool(вклtrue, выклfalse), моджно ввести массив bool[8], но лучше всего ввести ОДНУ переменную типа BYTE LampsStatus, у которой биты соответствуют состоянием лампочки - если бит №i равен 1 (обычно говорят "поднят"), то лампочка №i включена, если сброшен (0) - то выключена (i от до 7). Чем это лучше - а тем, что места меньше в памяти занимает, а еще тем, что управляться эти лампочки почти наверняка будут восемью логическими сигналами с, напрмер, паралельного порта PC. Допустим, надо включить все лампочки - пихаешь в порт восемь единиц: LampsStatus=0xFF //это и есть 11111111b или 255 outportb(port,LampStatus); Выключить: LampsStatus=0; outportb(.. четные (0ую,2ую, 4ую и т.д): LampsStatus=0x55; outportb(port,LampStatus);
Раз в секунду переключать четные и нечетные: BYTE LampsStatus=0x55; void OnTimer() { LampsStatus^=0xFF; outportb(port,LampStatus); } и т.д.
4. Можно делить/умножать только на 2,4,8,16,32,64..? как поделить/умножить на 3,5, если можно. Нет только на "круглые" числа - кратные степени 2 (привыкай, теперь 10 - не круглое, а круглые это 0,2,4,8,16,32,64 и т.д 0x0,0x2,0x4,0x8,0x10,0x20,0x40) 5. Как я понял, сдвиги используются только для деления/умножения на 2,4,8,16,32 , єто так? Нет конечно, не только - из моего примера: надо раз в секунду включать лампочки по-очереди: BYTE LampsStatus=0x1; void OnTimer() { LampsStatus |
|
Вернуться к началу |
|
|
Adil Гость
|
Добавлено: Вс Авг 04 2002 14:22 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Достал уж этот вебдизайн! Досылаю. [ и ] соответствуют угловым скобкам. Нет конечно, не только - из моего примера: надо раз в секунду включать лампочки по-очереди: BYTE LampsStatus=0x0; void OnTimer() { LampsStatus[[=1; if(LampsStatus==0) LampStatus=1; outportb(port,LampStatus); } а еще лучше BYTE LampsStatus=0x0; void OnTimer() { // циклический сдвиг - на С нет такого оператора, ИМХО asm rol LampsStatus, 1 outportb(port,LampStatus); } ]]6. Нужно ли запоминать "таблицы результатов" ]]операторов битовой арифметики, ели правильно ]]выразился.Если "да" то может имеется способ ]]как это лучше сделать?
Нет, конечно, не надо - надо запомнить только результаты булевой арифметики. Но это просто - там только 4 основные действия &,|,^,~.
Удачи. |
|
Вернуться к началу |
|
|
Anonymous Гость
|
Добавлено: Вс Авг 04 2002 20:07 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Спасибо, теперь еще более ясно зачем это нужно и как с этим работать. На сколько я понимаю, в основном такие операции используются в программировании на низшем уровне, т.е. для "управлением" всяческим железом. Пример с лампочками хорош, просто и понятно.
Получается что нет смысла использовать сабж в обычных приложениях? Т.е. скорости это не дасть. Разве что при компиляции, что повысит данный процесс? Если, как ты говоришь, все равно все числа преобразуется в двоичную.
Может я все же не понял с быстродействием, но выходит что только в скриптовых языках типа perl,php, где компиляция идет при каждом запуске, есть смысл использовать битовую арифметику да и вообще другие системы исчисления; также при прямой работе с железом, для которого это "родной язык". А сдвиги могут ускорить операции целочисленного деления, умножения числа на степени двойки.?? Правильно понял?
Перевести в 16ти-ричную можно только из двоичной, это так? И, получается что 16ти-ричное число может содержать как одну 16ти-ричную цифру, так и 21? |
|
Вернуться к началу |
|
|
xorxor Гость
|
Добавлено: Пн Авг 05 2002 07:37 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Дайте я тоже влезу
... Перевести в 16ти-ричную можно только из двоичной, это так?
перевести можно из любой в любую (хоть из пятеричной в двенадцатеричную) ведь как говорилось выше это только ПРЕДСТАВЛЕНИЕ числа, а само оно не меняется. Для этого надо исходное чило делить на основание новой системы счисления, запоминая остаток. Пример:
178 десятичное переводится в шестнадцатеричное: 178 / 16 = (11) * 16 + 2 = B2
... И, получается что 16ти-ричное число может содержать как одну 16ти-ричную цифру, так и 21
любое число в любой системе может содержать любое число цифр (в общем случае. (я не говорю о выделении фиксированного значения разрядов переменным в различных языках программирования)) |
|
Вернуться к началу |
|
|
gadyuka
Зарегистрирован: 12.11.2001 Сообщения: 36 Откуда: Moscow
|
Добавлено: Пн Авг 05 2002 08:14 Заголовок сообщения: Re: В некоторых приложениях... |
|
|
битовая логика не только увеличивает быстродействие, но и делает более прозрачным и удобным сам код - для программиста.
Пример практический - операции форматирования текстов. Допустим, текст может быть Bold, Italic, Underline и так далее, а кроме того выровнен по левому краю, по центру и так далее. Если все это добро описывать так, чтобы на каждую опцию приходилось по переменной - обязательно съедет башня. А с битовой системой описывается ОДНА переменная, типа TextStyle, и набор констант, например: txtNormal = 0x0000; txtBold = 0x0001; txtItalic = 0x0002; txtUnderline = 0x0004; txtStyle = 0x000F; txtAlLeft = 0x0100; txtAlCenter = 0x0200; txtAlRight = 0x0400; txtAlign = 0x0F00; txtVAlTop = 0x1000; txtVAlMiddle = 0x2000; txtVAlBottom = 0x4000; txtVAlign = 0xF000;
Теперь, чтобы нам отформатировать текст, например, сделать его одновременно Bold, Underline, по центру и снизу достаточно одной операции присваивания
TextStyle:=TextStyle and (not txtStyle) or txtBold or txtUnderline and (not txtAlign) or txtAlCenter and (not txtVAlign) or txtVAlBottom;
(выполняя and (not Something)) мы сбрасываем предыдущие установки формата текста.
Это также невероятно удобно, если параметры форматирования текста нам надо отобразить в юзерском интерфейсе. В нашем примере, если для каждой опции форматирования есть некая кнопка, статус этой кнопки будет вычисляться так: btnBold.Down = (TextStyle and txtBold)0 btnUnderline.Down = (TextStyle and txtUnderline)0 и т.д.
Собственно, подавляющее большинство функций WinAPI используют такие вот битовые константы.... так что.... ) |
|
Вернуться к началу |
|
|
xorxor Гость
|
Добавлено: Пн Авг 05 2002 08:16 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
... А сдвиги могут ускорить операции целочисленного деления, умножения числа на степени двойки.?? Правильно понял?
в принципе правильно, но только ускорение скорее всего на глаз не почувствовать:
shr xxx,1
исполняется на пару тактов быстрее чем
mov cx,2 div cx
И если ты это не повторяешь миллионы раз, то смысла нет этим заниматься.
Кстати, PHP и т.д. - интерпритаторы, и что там будет быстрее исполняться - сдвиг или деление - совсем не ясно. |
|
Вернуться к началу |
|
|
Adil Гость
|
Добавлено: Пн Авг 05 2002 10:39 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Спасибо всем за помощь в объяснениях. Надеюсь теперь коллега сам справиться...
Удачи всем. |
|
Вернуться к началу |
|
|
Anonymous Гость
|
Добавлено: Пн Авг 05 2002 14:25 Заголовок сообщения: Re: Помогите разобраться в битовой арифметике |
|
|
Всем огромное спасибо за ваше терпение и время. Для меня эта тема была самым большим барьером. Сейчас все намного понятнее, буду двигаться самостоятельно дальше. Еще раз спасибо. |
|
Вернуться к началу |
|
|
Борис Гость
|
Добавлено: Чт Авг 15 2002 17:52 Заголовок сообщения: Считаю, что г-н Anonymous должен г-ну Adil примерно 111110100 (двоичное) руб. |
|
|
Считаю, что г-н Anonymous должен г-ну Adil примерно 111110100 (двоичное) руб. |
|
Вернуться к началу |
|
|
Anonymous Гость
|
Добавлено: Чт Авг 15 2002 21:47 Заголовок сообщения: Re: Считаю, что г-н Anonymous должен г-ну Adil примерно 111110100 (двоичное) руб. |
|
|
Это точно.. |
|
Вернуться к началу |
|
|
Борис Гость
|
Добавлено: Пт Авг 16 2002 15:16 Заголовок сообщения: Хорошие константы придумали индейцы (ala Высоцкий, индейцы -- это Билли с его виндами) |
|
|
Константы -- это хорошо, а C++ для этого дела еще предлагает спец. структуры -- битовые поля, примерно так: struct { левый_поворот:1; скорость:2; правый_поворот:3; } панель_управления; И компилятор сам подставляет нужные ~&|.
/* далее */ панель_управления.левый_поворот=1; /* включить левую мигалку */ панель_управления.левый_поворот=0; /* выключить левую мигалку */ панель_управления.скорость=1; /* включить 1-у скорость */ панель_управления.скорость=2; /* включить 2-у скорость */
Естественно, диапазон значений зависит от количества бит, отведенных данному полю. В нашем случае панель_управления.левый_поворот от до 1, панель_управления.скорость от до 3
Пример использования в реальной жизни -- машинный формат текущих даты-времени, формат атрибутов файлов в dos/win. Левые/правые сдвиги в умножении на не-степени двойки тоже могут пригодиться: x*11 --> x*(8+2+1) --> x |
|
Вернуться к началу |
|
|
|