Ответы:
В Java int- 32 бита. А byteравно 8 bits.
Большинство примитивных типов в Java подписаны, и byte, short, int, и longкодируются в виде дополнения до двух. ( charТип беззнаковый, и понятие знака не применимо к boolean.)
В этой числовой схеме старший бит определяет знак числа. Если требуется больше бит, старший бит («MSB») просто копируется в новый MSB.
Итак, если у вас есть byte 255: 11111111
и вы хотите представить его как int(32 бита), вы просто копируете 1 влево 24 раза.
Теперь один из способов прочитать отрицательное число в дополнительном коде до двух - начать с младшего значащего бита, двигаться влево, пока не найдете первую единицу, а затем инвертировать каждый бит. Полученное число является положительной версией этого числа.
Например: 11111111идет к 00000001= -1. Это то, что Java будет отображать как значение.
Вы, вероятно, захотите узнать беззнаковое значение байта.
Вы можете сделать это с помощью битовой маски, которая удаляет все, кроме младших 8 бит. (0xff)
Так:
byte signedByte = -1;
int unsignedByte = signedByte & (0xff);
System.out.println("Signed: " + signedByte + " Unsigned: " + unsignedByte);
Распечатал бы: "Signed: -1 Unsigned: 255"
Что на самом деле здесь происходит?
Мы используем побитовое И, чтобы замаскировать все посторонние биты знака (1 слева от младших 8 бит). Когда int преобразуется в байт, Java отрезает самые левые 24 бита.
1111111111111111111111111010101
&
0000000000000000000000001111111
=
0000000000000000000000001010101
Поскольку 32-й бит теперь является битом знака вместо 8-го (и мы установили бит знака в 0, который является положительным), исходные 8 битов из байта считываются Java как положительное значение.
signedByte & (0xff)происходит, так 0xffэто то, что это межчисленный литерал, таким образом, signedByte становится целым перед выполнением побитовой операции.
132в цифрах ( база 10 ) - 1000_0100в битах ( база 2 ), а в Java хранится int32 бита:
0000_0000_0000_0000_0000_0000_1000_0100
Алгоритм преобразования целых чисел в байты - усечение слева; Алгоритм для System.out.printlnявляется дополнением до двух ( дополнение до двух - если крайний левый бит имеет значение 1, интерпретируется как отрицательное дополнение до единицы (инвертировать биты) минус один.); Таким образом System.out.println(int-to-byte( )):
0000_0000_0000_0000_0000_0000_1000_0100) [)))])1000_0100[)))])1000_0100))))1000_0011)))0111_1100))intв a byte- это преобразование с потерями (т. Е. Информация теряется). Следовательно, нет возможности преобразовать его обратно в исходное intзначение.
байт в Java подписан, поэтому он имеет диапазон от -2 ^ 7 до 2 ^ 7-1, т. е. от -128 до 127. Поскольку 132 больше 127, вы в конечном итоге оборачиваетесь до 132-256 = -124. То есть по существу 256 (2 ^ 8) добавляется или вычитается, пока не попадет в диапазон.
Для получения дополнительной информации вы можете прочитать о дополнении до двух .
132 находится вне диапазона байта, который составляет от -128 до 127 (от Byte.MIN_VALUE до Byte.MAX_VALUE). Вместо этого верхний бит 8-битного значения обрабатывается как знаковый, что указывает на то, что в данном случае оно отрицательное. Таким образом, число 132 - 256 = -124.
вот очень механический метод без отвлекающих теорий:
Этот более практичный метод соответствует приведенным выше теоретическим ответам. Итак, те, кто все еще читает книги по Java, в которых говорится об использовании по модулю, это определенно неверно, поскольку 4 шага, которые я описал выше, определенно не являются операцией по модулю.
http://iiti.ac.in/people/~tanimad/JavaTheCompleteReference.pdfстраница 59
Уравнение с дополнением до двух:
В Java byte(N = 8) и int(N = 32) представлены 2s-дополнением, показанным выше.
Из уравнения 7 отрицательно для, byteно положительно для int.
coef: a7 a6 a5 a4 a3 a2 a1 a0
Binary: 1 0 0 0 0 1 0 0
----------------------------------------------
int: 128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 = 132
byte: -128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 = -124
часто в книгах вы найдете объяснение преобразования типа int в byte как выполнения модульного деления. это не совсем правильно, как показано ниже, что на самом деле происходит: 24 старших бита из двоичного значения числа int отбрасываются, оставляя путаницу, если установлен оставшийся крайний левый бит, который обозначает число как отрицательное
public class castingsample{
public static void main(String args[]){
int i;
byte y;
i = 1024;
for(i = 1024; i > 0; i-- ){
y = (byte)i;
System.out.print(i + " mod 128 = " + i%128 + " also ");
System.out.println(i + " cast to byte " + " = " + y);
}
}
}
Быстрый алгоритм, имитирующий его работу, следующий:
public int toByte(int number) {
int tmp = number & 0xff
return (tmp & 0x80) == 0 ? tmp : tmp - 256;
}
Как это работает? Посмотрите на ответ daixtr . Реализация точного алгоритма, описанного в его ответе, следующая:
public static int toByte(int number) {
int tmp = number & 0xff;
if ((tmp & 0x80) == 0x80) {
int bit = 1;
int mask = 0;
for(;;) {
mask |= bit;
if ((tmp & bit) == 0) {
bit <<=1;
continue;
}
int left = tmp & (~mask);
int right = tmp & mask;
left = ~left;
left &= (~mask);
tmp = left | right;
tmp = -(tmp & 0xff);
break;
}
}
return tmp;
}
Если вы хотите понять это математически, например, как это работает
поэтому в основном числа ч / б от -128 до 127 будут записаны так же, как их десятичное значение, выше его (ваше число - 256).
например. 132, ответ будет 132 - 256 = - 124 т.е.
256 + ваш ответ в числе 256 + (-124) 132
Другой пример
double a = 295.04;
int b = 300;
byte c = (byte) a;
byte d = (byte) b; System.out.println(c + " " + d);
Выход будет 39 44
(295 - 256) (300 - 256)
ПРИМЕЧАНИЕ: он не будет рассматривать числа после десятичной дроби.
По сути, для вашего числа выполняются повторные вычитания 256, пока оно не окажется в диапазоне от -128 до +127. Итак, в вашем случае вы начинаете со 132, а затем заканчиваете -124 за один шаг.
С вычислительной точки зрения это соответствует извлечению 8 младших битов из исходного числа. (И обратите внимание, что старший бит из этих 8 становится битом знака.)
Обратите внимание, что в других языках это поведение не определено (например, C и C ++).
N is input number
case 1: 0<=N<=127 answer=N;
case 2: 128<=N<=256 answer=N-256
case 3: N>256
temp1=N/256;
temp2=N-temp*256;
if temp2<=127 then answer=temp2;
else if temp2>=128 then answer=temp2-256;
case 4: negative number input
do same procedure.just change the sign of the solution