Побитовые операторы в Java, действующие на два байта - PullRequest
2 голосов
/ 11 ноября 2010

Это должно быть просто, но у меня возникли проблемы с изменением некоторого кода C, который использует побитовые операторы и переключается на Java.

В C у меня есть:

unsigned short Color(byte r, byte g, byte b)
{
  return( ((unsigned short)g & 0x1F )<<10 | ((unsigned short)b & 0x1F)<<5 | (unsigned short)r & 0x1F);
}

Эта функция, Color, возвращает 16 бит, где 15 из них представляют три 5-битных значения для красного, зеленого и синего цветовых каналов. Я пытаюсь сделать что-то подобное в Java, но у меня проблемы с типами данных.

В Java у меня есть:

int r=someval, g=anotherval, b=yetanotherval;

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

Как лучше всего подойти к этому? Я думал о 2-байтовом массиве, но это кажется ненужным.

редактировать

Итак, я попробовал Java на шортах, но проблема все еще остается. Я начал просто с:

short r=someval, g=anotherval, b=yetanotherval;
short colorData = g & 0x001F;

Но компилятор жалуется: «не может преобразовать из int в short»

Ответы [ 5 ]

2 голосов
/ 11 ноября 2010

В вашем примере

short r=someval, g=anotherval, b=yetanotherval;
short colorData = g & 0x001F;

И g, и шестнадцатеричный литерал автоматически переводятся в int, поскольку логический оператор и оператор всегда работают и возвращают целые числа.Конечно, вы можете привести результат обратно к short.

short colorData = (short)(g & 0x001F);

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

2 голосов
/ 11 ноября 2010

В java все операции вычисления, даже с только типами, меньшими чем int, всегда приводят к int, поэтому вы должны явно привести его обратно к short:

short colorData = (short)(g & 0x001F);
2 голосов
/ 11 ноября 2010

У вас также есть тип short в Java, но он всегда подписан, в Java нет без знака.

Следовательно, может быть лучше использовать int, поэтому вам не нужно использовать знаковый бит для хранения фактических данных о цвете, что может немного сбить с толку (без каламбура!)

Это должно работать как отправная точка, как минимум:

int Color(int r, int g, int b)
{
  return ((g & 0x1F) << 10) | ((b & 0x1F) << 5) | (r & 0x1F);
}

Я также привел аргументы int, для простоты.

Обновление: Звучит (и кажется), как будто вы действительно можете использовать short, поскольку для цветового формата вам нужно всего лишь 15 бит. Тогда давайте сделаем это:

short Color(short r, short g, short b)
{
  return ((g & 0x1F) << 10) | ((b & 0x1F) << 5) | (r & 0x1F);
}

Я не пробовал скомпилировать вышеупомянутое, но, скорее всего, вы получите ошибки конвертации, и вам нужно будет добавить явные приведения short для его компиляции.

1 голос
/ 11 ноября 2010

Поскольку вы используете только 15 битов, знаковый бит для типа данных short не будет проблемой.

1 голос
/ 11 ноября 2010

char: тип данных char - это один 16-битный символ Unicode.Он имеет минимальное значение '\ u0000' (или 0) и максимальное значение '\ uffff' (или 65 535 включительно).

http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

Java charТип данных по умолчанию составляет 2 байта.

...