2010-03-16 2 views
14

Я знаю, что Java не разрешает неподписанные типы, поэтому мне было интересно, как это отличает целое число к байту. Скажем, у меня есть целое число a со значением 255, и я передаю целое число в байт. Является ли значение, представленное в байте 11111111? Другими словами, значение больше рассматривается как подписанное 8-битное целое число или просто копирует последние 8 бит целого числа?Как целые числа, передаваемые в байты в Java?

ответ

18

Это называется narrowing primitive conversion. В соответствии со спецификацией:

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

Так что это второй вариант, который вы указали (прямое копирование последних 8 бит).

Я не уверен в вашем вопросе, знаете ли вы, как представлены объявленные интегральные значения, поэтому просто для того, чтобы быть в безопасности, я укажу, что значение байта 1111 1111 равно -1 в системе two's complement (который использует Java).

+0

Да, я знал о дополнении двух. Итак, просто для уточнения, если у меня длинный тип со значением -1, и я передал его int, результат будет 65535? Спасибо за быстрый и подробный ответ. – LandonSchropp

+1

@helixed: Нет, это тоже будет -1, потому что это тоже все. Все, что находится в диапазоне меньшего типа, будет преобразовано в эквивалентное значение. –

+0

Ой, подождите. Из-за дополнения 2 любое отрицательное значение внутри диапазона меньшего типа будет дополнено 1 (в двоичном формате), так что результат всегда будет сохранять свой знак. Еще раз спасибо. – LandonSchropp

1

Только мысль о том, что сказано: Всегда маскируйте свое целое число при преобразовании в байты с 0xFF (для ints). (Предполагая, что myInt было присвоено значения от 0 до 255).

например.

char myByte = (char)(myInt & 0xFF); 

Почему? если myInt больше 255, просто приведение типа к байту возвращает отрицательное значение (дополнение 2), которое вы не хотите.

+0

char имеет два байта в java. – Paul

+3

'char' - 16 бит в java. Если вы измените свой пример на 'byte', он тоже не работает и все равно может дать отрицательное значение. Вы можете маскировать 0x7F, но тогда отрицательные значения не будут правильно преобразовываться. Хороший способ гарантировать, что вы не столкнетесь с проблемами, вероятно, для 'assert -128 <= myInt && myInt <= 127;' –

+0

@Philippe, спасибо. Я работаю очень поздно, поэтому я написал это слишком быстро, но все же, насколько большой «короткий» в java? –

2

или же она просто непосредственно скопировать последние 8 бит целое

да, это так, это литье работает

+0

Спасибо. Это действительно ключевой момент. – Hong

4
int i = 255; 

byte b = (byte)i; 

Таким образом, значение будет в гекс 0xFF, но десятичное значение будет равно -1.

int i = 0xff00; 

byte b = (byte)i; 

Значение b теперь равно 0x00. Это показывает, что java занимает последний байт целого числа. то есть. последние 8 бит, но это подписано.

0
for (int i=0; i <= 255; i++) { 
    byte b = (byte) i; // cast int values 0 to 255 to corresponding byte values 
    int neg = b;  // neg will take on values 0..127, -128, -127, ..., -1 
    int pos = (int) (b & 0xFF); // pos will take on values 0..255 
} 

Преобразование байта, содержащего значение больше, чем 127 (т.е. ,. значения 0x80 по 0xFF) к Int приводит к расширению знака бита высокого порядка значения байта (т.е., бит 0x80). Чтобы удалить «лишние» бит, используйте x & 0xFF; это заставляет биты выше 0x80 (т. е. биты 0x100, 0x200, 0x400, ...) равными нулю, но оставляет младшие 8 бит как есть.

Вы также можете написать их; все они эквивалентны: int pos = ((int) b) & 0xFF; // сначала конвертировать b в int, а затем вырезать старшие разряды int pos = b & 0xFF; // сделано как int арифметика - литой не требуется

Java автоматически «продвигает» целые типы, размер которых (в количестве бит) меньше, чем значение int при выполнении арифметики. Это делается для обеспечения более детерминированного результата (чем C, который менее ограничен в своей спецификации).

Вы можете посмотреть на this question on casting a 'short'.

0

Это моя версия литья любой возможный объект Byte

private Byte castToByte(Object value, Byte def) 
{ 
    if (value instanceof Integer) 
    { 
     return ((Integer) value).byteValue(); 
    } 
    else if (value instanceof Number) 
    { 
     return ((Number) value).byteValue(); 
    } 
    else if (value instanceof String) 
    { 
     return Byte.valueOf((String) value); 
    } 
    return def; 
} 
0

По моему разумению, вы имели в виду

Integer я = новый Целое число (2);
байт b = i; // не будет работать

final int i = 2;
байт b = i; // fine


Байт b = новый Байт (2);
int a = b; // fine

0

Байт 8 бит. 8 бит может представлять 256 номеров. (2 рейза до 8 = 256)
Теперь первый бит используется для обозначения. [если положительный, тогда первый бит = 0, если отрицательный первый бит = 1]
, предположим, вы хотите преобразовать целое число 1099 в байт. просто разделите 1099 на 256. остатка ваш байт представление Int
примеры
1099/256 => остаток = 75
-1099/256 => остаток = -75
2049/256 => остаток = 1
причина почему? посмотреть на это изображение http://i.stack.imgur.com/FYwqr.png

Смежные вопросы