int
к типу short
или byte
, результаты бывают неожиданными? Давайте разбираться!
int i = 450;
byte b = (byte)i;
System.out.println(b);
Результат на экране:
-62
Неожиданно, но этому есть логическое объяснение, более того, это действие можно сделать собственноручно. Для этого, нам нужно перевести 450 из десятичной системы в двоичную:
450/2. 0
225/2. 1
112/2. 0
56/2. 0
28/2. 0
14/2. 0
7/2. 1
3/2. 1
1/2. 1
В правый столбик от числа мы записываем его остаток от деления на 2, а под самим числом пишем результат деления нашего числа на два, если остаток 0. Если остаток 1, то ниже записываем целую часть от деления на два. (Онлайн калькулятор с объяснением вычислений).
В итоге, мы получаем, что в двоичной системе счисления 450 = 11100 0010
.
Любое число типа int
занимает 4 байта или 32 бита, где каждый бит - это 0 или 1. В нашем случае заняты только 9 битов, и в принципе наш int i = 450
в двоичной системе выглядит так:
0000_0000_0000_0000_0000_0001_1100_0010
Мы хотим записать нашу переменную в переменную типа byte
, но число типа byte
занимает 1 байт (следует из названия этого типа) или 8 бит. Поэтому лишние биты слева просто отбрасываются, и в итоге мы получаем:
1100 0010
Диапазон значений типа byte
: -128 до 127. Каждое число занимает 8 бит и у каждого числа крайний левый бит - знаковый бит(sign bit). У всех положительных чисел он равен 0, у всех отрицательных он равен 1.
Спешить переводить наш результат, полученный выше, в 10-ную систему не нужно, т.к. мы получили дополнительный код искомого числа, а не прямой. Крайний бит слева получился равен 1, следовательно число у нас отрицательное, а у отрицательных чисел прямой и обратный код не совпадает, в отличие от положительных. Если бы знаковый бит был равен 0, то мы могли бы сразу перевести число в десятичную систему счисления и получить: 66.
Но знаковый бит отрицательный, поэтому сначала дополнительный код нужно перевести в прямой и добавить к ответу знак минус.
Для наглядности и тренировки, сначала попробуем получить дополнительный код какого-нибудь числа, например -15. Для этого в прямом коде его положительного представления (числа 15) нужно поменять все 0 на 1 и наоборот (получить обратный код, также называют инверсный), а затем добавить к результату единицу.
В десятичной системе 15 = 0000 1111
;
Обратный код (меняем все 0 на 1 и наоборот) = 1111 0000
;
Дополнительный код(прибавляем единицу):
1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 1
1 1 1 1 0 0 0 1
Дополнительный код числа -15: 1111 0001
;
Отлично.Теперь, по аналогии с примером выше, нам нужно перевести уже наш дополнительный код в прямой, напомню, он равен 1100 0010
.
Отнимаем единицу и получаем обратный код. Удобно делать так, записать дополнительный код в ответ и смотреть, к чему нужно прибавить единицу, чтобы получить такой дополнительный код. Начинаем с крайнего правого разряда и смотрим: к чему нужно прибавить 1 чтобы получить 0? К 1, получим 10, 0 уходит в ответ, а единичка на следующий разряд. Далее, что нужно прибавить к 0, чтобы получить один. Единицу, но так как мы с предыдущего разряда имеем единичку, то в ответ пишем 0. Далее, чтобы получить 0, что нужно прибавить к 0? Конечно, 0. Так ещё 4 раза. И остались последние 2 разряда, где к 0 надо что-то прибавить, чтобы получить 1. Конечно, в обоих случаях нужно прибавить 1. Итого:
1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0
Самое сложное позади! Мы получили инверсный(обратный) код и нам осталось получить прямой. Инвертируем все 0 на 1 и наоборот:
1100 0001
- инверсный код;0011 1110
- прямой код нашего числа, точнее его положительного представления;Переводим в десятичную систему счисления (Онлайн калькулятор с объяснением вычислений):
0011 1110 = 0∙2^7+0∙2^6+1∙2^5+1∙2^4+1∙2^3+1∙2^2+1∙2^1+0∙2^0 = 0+0+32+16+8+4+2+0 = 62;
Осталось только добавить к числу минус и наш ответ:
-62.
short
к типу int
:
int i = 10_000_000;
short s = (short)i;
System.out.println(s); // -27008
10.000.000 в 10-ной системе счисления =
0000 0000 1001 1000 1001 0110 1000 0000
в 2-ной.В Java число типа
int
занимает 4 байта, аshort
- 2 байта, или 16 бит, поэтому отсекаем слева до 16 цифр:Переводим в обратный код:
1 0 0 1 0 1 1 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0
Обратный код:
1001 0110 0111 1111
;Инвертируем и получаем прямой код:
0110 1001 1000 0000
.Переводим в двоичную систему счисления и получаем положительное представление нашего числа:
1∙2^14+1∙2^13+1∙2^11+1∙2^8+1∙2^7 = 16384+8192+2048+256+128 = 27008.
Добавляем минус и получаем ответ:
-27008
1001 0110 1000 0000
.
Крайний левый бит(старший бит, он же знаковый бит) получился равен 1. Значит перед нами дополнительный код отрицательного числа, поэтому переходим к следующему пункту.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ