Статьи

Кодирование: визуализация растрового изображения

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

В частности, мне нравится метод toString, который возвращает двоичное представление значений, которые мы храним в байтах, целых и длинных значениях.

Я подумал, что было бы забавно попробовать написать свою собственную функцию, которая берет 32-битную карту и возвращает строку, содержащую 1 или 0, в зависимости от того, установлен бит или нет.

Ключевым моментом является то, что нам нужно выполнить итерацию вниз от бита самого высокого порядка, а затем создать битовую маску этого значения и выполнить ее побитово и с полной битовой картой. Если результат этого вычисления равен 0, то бит не установлен, в противном случае он установлен.

Например, чтобы проверить, был ли установлен бит самого высокого порядка (индекс 31), в нашей битовой маске должен быть установлен 32-й бит, а все остальные — 0.

1
2
java> (1 << 31) & 0x80000000
java.lang.Integer res5 = -2147483648

Если бы мы хотели проверить, был ли установлен бит самого низкого порядка, мы бы запустили это вычисление:

1
2
3
4
5
java> (1 << 0) & 0x00000001
java.lang.Integer res7 = 0
  
java> (1 << 0) & 0x00000001
java.lang.Integer res8 = 1

Теперь давайте поместим это в функцию, которая проверяет все 32 бита растрового изображения, а не только те, которые мы определяем:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
private String  asString( int bitmap )
{
    StringBuilder sb = new StringBuilder();
    sb.append( "[" );
    for ( int i = Integer.SIZE - 1; i >= 0; i-- )
    {
        int bitMask = 1 << i;
        boolean bitIsSet = (bitmap & bitMask) != 0;
        sb.append( bitIsSet ? "1" : "0" );
  
        if ( i > 0 &&  i % 8 == 0 )
        {
            sb.append( "," );
        }
    }
    sb.append( "]" );
    return sb.toString();
}

И быстрый тест, чтобы проверить это работает:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@Test
public void shouldInspectBits()
{
    System.out.println(asString( 0x00000001 ));
    // [00000000,00000000,00000000,00000001]
  
    System.out.println(asString( 0x80000000 ));
    // [10000000,00000000,00000000,00000000]
  
    System.out.println(asString( 0xA0 ));
    // [00000000,00000000,00000000,10100000]
  
    System.out.println(asString( 0xFFFFFFFF ));
    // [11111111,11111111,11111111,11111111]
}

Ухоженная!