Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Побитовые операции, использовать или нет 
:(
    Опции темы
serghd
Дата 9.2.2010, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



В последнее время часто слышу, что для экономии лучше использовать побитовые операции и представления (слышал что-то типа "в один int можно запихнуть 32 значения" и т.п.), но в связи с этим возникает много вопросов. 
1) где об этом можно НОРМАЛЬНО ознакомиться? В инете инфа есть, но всё размыто, разные источники пихают разное. 
2) целесообразно ли их применение в принципе? 
3) Как называется, например, это "0x1" представление единицы (шестнадцатеричное?) ? И как вообще числа в это представление переводить, может есть какие-то функции в java для этого? Опять же, желательны пруфлинки с подробным описанием.
Пример:
Код

 public static final int TEST = 0x1;
 public static final int NO_TEST = 0x2;

// TEST | NO_TEST даёт 3, ПОЧЕМУ?

Вобщем, интересен весь глубокий смысл этих операций и еже с ними учитывая что в этой теме я полный ноль. Спасибо понимающим заранее.



Это сообщение отредактировал(а) serghd - 9.2.2010, 12:36
PM MAIL   Вверх
magicfly
Дата 9.2.2010, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



...01
...10
Результат "или" очевидно будет 3
Вообще ради одного булеана не стоит делать подобным образом. А массив булеанов и так оптимизирован
http://java.sun.com/docs/books/jvms/second....doc.html#22909

Это сообщение отредактировал(а) magicfly - 9.2.2010, 14:26
PM MAIL   Вверх
LSD
Дата 9.2.2010, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Цитата(serghd @  9.2.2010,  12:33 Найти цитируемый пост)
1) где об этом можно НОРМАЛЬНО ознакомиться? В инете инфа есть, но всё размыто, разные источники пихают разное.

Начни с архитектуры ЭВМ, байты, биты, представление в памяти (если конечно не в курсе). Думаю введение и самое начало в какой нибудь книжке о ассемблеру для начинающих, будет достаточно. Потом посмотри Арифметические и побитовые операторы языка Java.


Цитата(serghd @  9.2.2010,  12:33 Найти цитируемый пост)
2) целесообразно ли их применение в принципе? 

Иногда целесообразно, иногда нет, а иногда это единственная возможность smile Все зависит от задачи.


Цитата(serghd @  9.2.2010,  12:33 Найти цитируемый пост)
Как называется, например, это "0x1" представление единицы (шестнадцатеричное?) ?

Да.


Цитата(serghd @  9.2.2010,  12:33 Найти цитируемый пост)
И как вообще числа в это представление переводить, может есть какие-то функции в java для этого?

Тут надо понимать, что как ты в коде не запиши число она внутри класса будет хранится в одном и том же формате, различается только текстовое представление. У Integer.toString() есть перегруженный метод которому можно указать основание (десятичное, шестнадцатеричное, восьмеричное и т.п.).


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 9.2.2010, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



LSD, тему завёл, в том числе, из-за одной из твоих статей, где ты указал 
Код

private static final long MASK = 0xFFFFFFFFL;

Почему именно в этом виде, какой у неё int-эквивалент и как ты делаешь это преобразование?
PM MAIL   Вверх
Fieral
Дата 9.2.2010, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



0xFFFFFFFF = 4294967295
преобразование можно сделать калькулятором в Windows
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
LSD
Дата 9.2.2010, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Для начала прочти про дополнительный код.


В данном случае проблема состоит в том, что int расширяется до long как знаковое целое. Применительно к тому случаю: пусть у нас есть такой IP - 192.168.1.1 если перевести его в шестнадцатеричное представление C0.A8.01.01 или int - 0xC0A80101 (в десятичном представлении это -1062731519). А нам нужно получить не отрицательное целое. Поэтому нам надо расширить int до long, но так чтобы получилось положительное число (иначе их нельзя будет сравнивать операторами <>).
Код

  public static void main(String[] args)
  {
    int ipInt = 0xC0A80101;
    long ipLong = 0xC0A80101L;
    System.out.println("int dec = " + Integer.toString(ipInt, 10));
    System.out.println("int hex = " + Integer.toString(ipInt, 16));
    System.out.println("long dec = " + Long.toString(ipLong, 10));
    System.out.println("long hex = " + Long.toString(ipLong, 16));
    System.out.println("int as long hex = " + Long.toString((long) ipInt, 16));
    System.out.println("int as long + MASK hex = " + Long.toString(MASK & ipInt, 16));
  }




--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
andrew_121
Дата 11.2.2010, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

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



Цитата(Fieral @  9.2.2010,  15:54 Найти цитируемый пост)
0xFFFFFFFF = 4294967295

слишком гиморно smile 

как-то так.
Код

((unsigned)-1)


но что-то я не видел в яве беззнаковых целых...гм..


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
LSD
Дата 12.2.2010, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Цитата(andrew_121 @  11.2.2010,  16:59 Найти цитируемый пост)
как-то так.

Индусятина в чистом виде!


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
ivanovpv
Дата 19.2.2010, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Варвар
**


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

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



Цитата(serghd @  9.2.2010,  12:33 Найти цитируемый пост)
Вобщем, интересен весь глубокий смысл этих операций и еже с ними учитывая что в этой теме я полный ноль. Спасибо понимающим заранее.


Глубокий смысл интересен для людей близких к железу - программирующих на уровне ассемблера или хотя бы С/С++ для драйверов и проч.  Там надо четко понимать что такое BIG ENDIAN/LOW ENDIAN каково представление того или иного типа в битах, танцы с бубнами вокруг singed/unsigned и проч. Для джаверов - особого смысла в этом нет, поскольку мы довольно сильно оторваны от железа - в виде занавески называемой Java Virtual Machine.

На моей Java практике побитовые операции использовались только для убыстрения критичных участков кода или когда нужны какие-то специфические операции. Например надо сохранить int в файле, затем восстановить. Класс читатель/писатель по каким-то причинам пишет и читает только байтами (например операции персистентности в J2ME работаю только с массивами байт). Сразу же встает вопрос разложения целого на массив байтов и наоборот:
Код

    public static int byteArrayToInt(byte[] buffer, int offset)
    {
        int val = 0;
        for ( int i=0; i<4; i++ )
        {
            int shift = 3-i;
            val |= (buffer[offset+i]<<shift);
        }
        return val;
    }

Хотя конечно же можно решить задачу по другому - чисто в духе Java. Взять байтовый буфер, обернуть его в поток, писать в этот поток нормальные типы, а потом из буфера выцеплять массив байтов. Но с точки зрения быстродействия - это жесть.

Много используется битовых операций при разработке графики или алгоритмов шифрования/хэширования - то есть там где нужна мощная целочисленная арифметика и есть опасение, что компилятор напортачит в алгоритмах.

Классикой жанра является побитовая сдвижка вправо/влево вместо деления/умножения на 2 (здесь есть свои подводные камни - не все так просто и проч):
Код

    int n=10;
    n = 2*n; //обычное умножение на 2
    n = n << 1; //быстрое умножение на 2


В общем не советую сильно увлекаться побитовыми операциями - все должно быть подчинено здравому смыслу + решаемой задаче.


--------------------
Aut viam inveniam aut faciam
PM MAIL Skype   Вверх
W0LF
Дата 19.2.2010, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

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



Не знаю, в свое время все умножения/деления двойки менял на сдвиги, все циклы менял на убывание - прирост производительности был существенным
Цитата

(здесь есть свои подводные камни - не все так просто и проч)

а что за подводные камни при сдвигах влево/вправо?


--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
LSD
Дата 19.2.2010, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Цитата(W0LF @  19.2.2010,  15:03 Найти цитируемый пост)
а что за подводные камни при сдвигах влево/вправо? 

Неочевидность, когда мы пишем i * 2, тут сразу ясно что происходит. А вот i >> 1, далеко не так очевидно.

Ну и плюс всякие хитрости, типа такого:
Код

short i = -1;
while((i >>= 1) != 0) ;
System.out.println("Finished");


На мой взгляд самое частое применения битовых операций это реализация всяких бинарных протоколов и преобразование кодировок.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

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

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


 




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


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

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