Зачем минус примитивным типам данных?
Есть массив байтов. Необходимо извлечь 12 младших бит первых двух байтов - порядковый номер (4096 значений). Правильно ли решаю задачу? Для наглядности такое решение:
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(String.format("%8s", Integer.toBinaryString(b1 & 0xFF)).replaceAll(" ", "0"));
stringBuilder.append(String.format("%8s", Integer.toBinaryString(b2 & 0xFF)).replaceAll(" ", "0"));
return Integer.parseInt(stringBuilder.substring(4), 2);
С побитовыми операциями (возвращается int):
return ((byte1 & 0xFF) << 8 | (byte2 & 0xFF)) & 0xFFF;
Почему в 10-й системе исчисления байт представлен диапазоном -128..+128, а не 0..256? Зачем при расширении типа у "отрицательного" байта старшие биты автоматом заполняются единицами. И не теряю ли я данные, используя маску для исключения этих самых единиц.
Ответы (1 шт):
В Java нет беззнаковых типов (за исключением char). Почему - историки Java, вероятно, знают. Дядюшка Гослинг говорит о простоте и необходимом минимуме. Без беззнаковых обойтись, в общем, можно, а вот без отрицательных неприятно.
Gosling: For me as a language designer, which I don't really count myself as these days, what "simple" really ended up meaning was could I expect J. Random Developer to hold the spec in his head. That definition says that, for instance, Java isn't -- and in fact a lot of these languages end up with a lot of corner cases, things that nobody really understands. Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is. Things like that made C complex. The language part of Java is, I think, pretty simple. The libraries you have to look up.
Почему в 10-й системе исчисления байт представлен диапазоном -128..+128, а не 0..256?
Байт в памяти представлен восемью битами, а уж как их интерпретировать - зависит от языка, типа данных, программиста. 256 возможных значений - это -128..+127 для int8 (в Java только так), или 0..255 для uint8, или один AnsiChar (в Java отсутствуют).
Зачем при расширении типа у "отрицательного" байта старшие биты автоматом заполняются единицами - дык чтобы сохранялось значение
-1 = 0b11111111 = 0b1111111111111111
если заполнить нулями, то получится
0b0000000011111111 = 255
И не теряю ли я данные - для извлечения битов - нет. Обратите внимание, что формула попроще:
byte byte1 = -1; //0b11111111
byte byte2 = 1;
int r = (byte1 & 0x0F) << 8 | byte2;
System.out.println(r);
Даёт 3841 = 0b111100000001.