Как Java конвертирует int в байты?

int i =132;
byte b =(byte)i;
System.out.println(b);

Выходной сигнал -124

Почему? Я знаю, что это очень простой вопрос, но я все еще не могу его сопоставить или понять, как это происходит?

Ответ 1

В Java int - 32 бита. byte имеет 8 bits.

Большинство примитивных типов в Java подписаны, а byte, short, int и long кодируются в два дополнения. (Тип char имеет знака, а понятие знака не применимо к boolean.)

В этой схеме номера наиболее значимый бит указывает знак числа. Если требуется больше бит, самый старший бит ("MSB") просто копируется в новый MSB.

Поэтому, если у вас есть байт 255: 11111111 и вы хотите представить его как int (32 бита), вы просто копируете 1 влево 24 раза.

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

Например: 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 как положительное значение.

Ответ 2

Чтобы понять, как это работает, нам нужно знать, что компьютеры работают в битах.

132 в base 10 (десятичный) 10000100 в base 2 (двоичный код). Поскольку Java хранит int в 32 битах, мы имеем

00000000_00000000_00000000_10000100

Когда int преобразуется в byte, Java прерывает самые последние 24 бита. Мы получаем 10000100.

В два дополнения, самый левый бит используется как знак. Если самый левый бит 0, ничего больше не будет сделано.

Если самый левый бит 1 (как мы здесь имеем), это означает, что число отрицательно и требуется больше работы. Чтобы получить величину, мы минус один, затем применим один дополнительный вариант (примените одно дополнение означает, что мы инвертируем бит):

  • 10000100 - 1 = 10000011

  • Инвертировать 10000011= 01111100

01111100 при интерпретации десятичного числа равен 124.

Итак, у нас есть отрицательное число с величиной 124, что дает нам -124.

Ответ 3

байт в Java подписан, поэтому он имеет диапазон от -2 ^ 7 до 2 ^ 7-1, т.е. от -128 до 127. Поскольку 132 превышает 127, вы обертываете до 132-256 = -124. То есть, по существу, 256 (2 ^ 8) добавляется или вычитается до тех пор, пока он не попадает в диапазон.

Для получения дополнительной информации вы можете прочитать два дополнения.

Ответ 4

132 находится вне диапазона байта, который составляет от -128 до 127 (Byte.MIN_VALUE до Byte.MAX_VALUE) Вместо этого верхний бит 8-битного значения рассматривается как подписанный, который указывает, что в этом случае он отрицательный. Таким образом, число равно 132 - 256 = -124.

Ответ 5

здесь очень механический метод без отвлекающих теорий:

  • Преобразование числа в двоичное представление (используйте калькулятор в порядке?)
  • Скопируйте только самые правые 8 бит (LSB) и отбросьте остальные.
  • Из результата шага # 2, если крайний левый бит равен 0, используйте калькулятор для преобразования числа в десятичное. Это ваш ответ.
  • Else (если самый левый бит равен 1), ваш ответ отрицательный. Оставьте все самые правые нули и первый ненулевой бит без изменений. И отменили остальные, т.е. Заменили 1 на 0 и 0 на 1. Затем используйте калькулятор для преобразования в десятичный знак и добавьте отрицательный знак, чтобы указать, что значение отрицательное.

Этот более практичный метод соответствует многим теоретическим ответам выше. Итак, те, кто все еще читают эти Java-книги, говорящие, что используют modulo, это определенно неправильно, поскольку 4 шага, которые я изложил выше, определенно не являются модульной операцией.

Ответ 6

Двухкомпонентное уравнение:

введите описание изображения здесь


В Java byte (N = 8) и int (N = 32) представлены приведенным выше 2s-дополнением.

Из уравнения a 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

Ответ 7

часто в книгах вы найдете объяснение кастинга от int до байта как выполняемое модульным разделением. это не является строго правильным, как показано ниже то, что на самом деле происходит, это 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);

    }

}

}

Ответ 8

Быстрый алгоритм, который имитирует способ его работы, следующий:

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;
}

Ответ 9

Концептуально повторяющиеся вычитания 256 выполняются на ваш номер, пока он не будет в диапазоне от -128 до +127. Итак, в вашем случае вы начинаете с 132, а затем заканчиваете на -124 за один шаг.

Вычислительно это соответствует извлечению 8 младших значащих бит из вашего исходного номера. (И обратите внимание, что самый старший бит этих 8 становится знаковым битом.)

Обратите внимание, что в других языках это поведение не определено (например, C и С++).

Ответ 10

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

так что в основном числа от ч/б -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)

ПРИМЕЧАНИЕ: он не будет учитывать числа после десятичной дроби.

Ответ 11

 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