максимальное значение которое можно хранить в переменной типа int в языке java

Введение в примитивы Java

Изучите основы примитивных типов данных Java.

1. Обзор

Язык программирования Java содержит восемь примитивных типов данных.

В этой статье мы вспомним, что такое примитивы, и рассмотрим их.

2. Примитивные Типы Данных

Они хранятся непосредственно в стеке (проверьте эту статью для получения дополнительной информации об управлении памятью в Java).

Давайте рассмотрим размер хранилища, значения по умолчанию и примеры использования каждого типа.

Давайте начнем с краткой справки:

байт байт; 27– 1 -27 8
короткий короткий; 215– 1 -215 16
инт инт; 231– 1 -231 32
длинный длинный; 263– 1 -263 64
плыть поплавок.456f; (2-2-23)·2127 -2-149 32
двойной двойной номер 456789012345678; (2-2-52)·21023 -2-1074 64
обуглить обуглить; 216– 1 0 16
логический логический; 1

2.1. int

Мы можем просто объявить int просто:

Значение по умолчанию инт объявлено без присвоения равно 0.

Если переменная определена в методе, мы должны присвоить ей значение, прежде чем использовать ее.

Мы можем выполнять все стандартные арифметические операции над int s. Просто имейте в виду, что десятичные значения будут обрезаны при выполнении их на целых числах.

2.2. байт

Мы можем создать байт :

Значение по умолчанию байт также равно 0.

2.3. короткие

short объявляется следующим образом:

Также, как и для других типов, значение по умолчанию равно 0. Мы также можем использовать всю стандартную арифметику.

2.4. длинные

Мы можем просто объявить один:

2.5. поплавок

Мы объявляем float s таким же, как и любой другой тип:

Мы также можем выполнять все стандартные арифметические операции над float s. Однако важно отметить, что мы выполняем арифметику с плавающей запятой совсем иначе, чем целочисленную арифметику.

2.6. двойной

Далее мы рассмотрим double – его название происходит от того, что это десятичное число двойной точности.

Объявление double – это то же самое, что и другие числовые типы:

Значение по умолчанию также равно 0.0, как и в случае с float. Аналогично float, мы прикрепляем букву D для обозначения литерала как двойника.

2.7. булево

Однако для удобства Java заполняет значение и сохраняет его в одном байте.

Объявите boolean вот так:

2.8. char

Давайте теперь объявим a char :

При определении наших переменных мы можем использовать любой символьный литерал, и они автоматически преобразуются для нас в свою кодировку Unicode. Значение по умолчанию для символов равно ‘/u0000’.

2.9. Переполнение

Примитивные типы данных имеют ограничения по размеру. Но что произойдет, если мы попытаемся сохранить значение, которое больше максимального?

Когда целое число переполняется, оно переходит к минимальному значению и начинает отсчет оттуда.

Переполнение чисел с плавающей запятой путем возврата бесконечности. Когда они уменьшаются, они возвращают 0.0.

Underflow – это та же проблема, за исключением тех случаев, когда мы храним значение меньше минимального.

2.10. Автобоксинг

3. Заключение

В этом уроке мы рассмотрели восемь примитивных типов данных, поддерживаемых в Java.

Это строительные блоки, используемые большинством, но не всеми программами Java, поэтому стоит понять, как они работают.

Источник

Максимальное значение которое можно хранить в переменной типа int в языке java

Если статья вам понравилась, то можете поддержать проект.

Вселенная Java состоит из трёх субстанций: примитивы, объекты и коты. Про последних в документации ничего не говорится, поэтому их рассматривать не будем, но они существуют!

Примитивные типы Java не являются объектами. К ним относятся:

Примитивный в данном случае не оскорбление, а просто даёт понять, что речь идёт о простом типе, который не умеет прыгать, спать или мяукать. Да что он вообще умеет? Ой, всё.

Простые числовые типы

Тип Разрядность MIN MAX
byte 8 бит -128 127
short 16 бит -32768 32767
int 32 бит -2147483648 2147483647
long 64 бит -9223372036854775808 9223372036854775807
float 32 бит -3.4E+38 3.4E+38
double 64 бит -1.7E+308 1.7E+308

Целочисленные типы

Java определяет четыре целочисленных типа: byte, short, int, long. Они могут быть положительными и отрицательными (Java не поддерживает только положительные значения без знака, как некоторые языки программирования).

Тип byte

Объявить переменную типа byte можно следующим образом:

В арифметических выражениях с переменными типа byte вычисления выполняются как с типом int, т.е. с помощью 32-битовой арифметики, а полученный результат будет 32-битовым. Смотри пример с short.

Строку с числом перевести в данный тип можно через метод parseByte(String):

Класс Byte является оболочкой для данного типа. Без необходимости не используйте в Android класс Byte.

Слово «байт» (byte) возникло в компании IBM примерно в 1956 году. Оно произошло от слова bite («кусок»), но его было решено писать через букву y, чтобы не путать со словом «bit» («бит»). В течение некоторого времени слово «байт» обозначало просто число битов в конкретном потоке данных. Однако в середине 1960-х, в связи с разработкой семейства компьютеров System/360 в компании IBM, это слово стало обозначать группу из восьми бит.

Любопытно, что bite имеет также значение «укус» (сущ.) или «укусить» (глагол). Таким образом это наш родной «Кусь!»

Тип short

В арифметических выражениях с переменными типа short вычисления выполняются как с типом int, т.е. с помощью 32-битовой арифметики, а полученный результат будет 32-битовым. Например, такой код не пройдёт.

Java будет ругаться на последнюю строчку, так как итоговый результат не может быть short. Как вариант, вам нужно преобразовать результат снова в 16-битовое число.

Явно перевести строку с числом в тип short можно через метод parseShort(String):

Класс Short является оболочкой для данного типа. Без необходимости не используйте в Android класс Short.

Тип int

Сказка про тип int

Зададим себе вопрос, насколько большим может быть целое число типа int?

Напишем простую программу, где будем умножать переменную саму на себя. Для начала присвоим ей значение 2, а дальше строчка за строчкой будем выводить результат. Результаты будем отдавать коту учёному LogCat. Весь код поместим в обработчик события щелчка на кнопке нашей учебной программы, а первую строчку поместим выше её.

Запустите программу и нажмите кнопку. В нижней части студии откройте панель Android Monitor и в ней вкладку logcat. Настройте его фильтр, чтобы отображались только наши сообщения. В результате мы получим такую картину:

Что за бред, скажете вы. Когда мы умножаем 65536 на себя, то получаем 0 (Только не говорите об этом учительнице по математике). А потом, естественно, программа умножает 0 на 0 и продолжает выводить результаты.

Вы ещё больше удивитесь, если в качестве начального значения возьмёте число 3. На этот раз вы сможете получить даже отрицательные значения.

Проверьте самостоятельно. Если вы и это попытаетесь доказать учительнице, то исключение из учебного заведения вам гарантировано.

Деление целочисленных чисел

Запомните, что при делении целочисленных чисел остаток отбрасывается. Поэтому следующие примеры вернут один и тот же результат. Бедная учительница, её увезут в психушку.

Читайте также:  можно ли убрать щербинку между зубами с помощью брекетов

На ноль делить нельзя, увидите ошибку.

Если нужен узнать остаток от деления, то используйте оператор % (оператор деления по модулю).

Также есть специальный класс BigInteger для проведения арифметических действий повышенной точности (финансовые расчёты).

В Java 7 можно использовать знак подчёркивания для удобства. Например, так:

Компилятор не обращает внимания на эти знаки, а человеку проще понять, что ему предлагают миллион или миллиард. В Android относительно недавно появилась полноценная поддержка Java 7 и вам в настройках нужно указать новую версию компилятора.

Этот приём относится не только к int, но и к другим типам чисел.

Как сконвертировать строку или CharSequence в int?

Если у вас тип CharSequence, то его можно сконвертировать сначала в строку при помощи метода toString(), а потом в int.

Метод parseInt() предпочтительнее метода valueOf():

Как сконвертировать число в строку?

Если сложить число и строку, то Java автоматически конвертирует число в строку. Пользуясь этим свойством, программисты часто прибавляют к числу пустую строку. Но лучше использовать метод valueOf():

Добавить ведущие нули

Если мы хотим получить строку из числа, добавим при этом несколько нулей вначале, то поможет метод format(), только учитывайте число цифр в самом числе.

Тип long

Можно использовать символы l или L для обозначения числа типа long. Рекомендую использовать заглавную букву, чтобы избежать возможной путаницы. Например, напишем пример:

Конвертируем строку в данный тип.

Класс Long является оболочкой для данного типа. Без необходимости не используйте в Android класс Long.

Типы с плавающей точкой

Числа с плавающей точкой (иногда их называют действительными числами) применяются при вычислении выражений, в которых требуется точность до десятичного знака. Например, это может быть вычисление квадратного корня, значений синуса, косинуса и т.п. Существует два типа с плавающей точкой: float и double, которые представляют числа одинарной и двойной точности.

Слово «плавающая» означает, что десятичная точка может располагаться в любом месте (она «плавает»). Вот коты плавать не особенно любят, поэтому они не float и не double.

Тип float

Тип float определяет значение одинарной точности, которое занимает 32 бит. Переменные данного типа удобны, когда требуется дробная часть без особой точности, например, для денежных сумм.

Рекомендуется добавлять символ F или f для обозначения этого типа, иначе число будет считаться типом double.

Конвертируем из строки.

Класс Float является оболочкой для данного типа. Без необходимости не используйте в Android класс Float.

Также есть специальный класс BigDecimal для проведения арифметических действий повышенной точности (финансовые расчёты).

Тип double

Тип double содержит не только числа, но и слова. Сейчас вам докажу. Разделим число типа double на ноль. Ошибки не произойдёт.

Пример вернёт значение Infinity (Бесконечность). Если разделить отрицательное число на ноль, то вернётся -Infinity.

А что произойдёт, если сложить две бесконечности? Если рассуждать логически, то сломается интернет, наступит конец света или можно вызвать Волдеморта. Я долго не решался, но потом набрался храбрости и попробовал.

Умножать две бесконечности я побоялся. И вам не советую.

Класс Double является оболочкой для данного типа. Без необходимости не используйте в Android класс Double.

Конвертация строки в double

Есть несколько вариантов.

Конвертация double в строку

При работе с числами double следует держать ухо востро. Рассмотрим пример конвертации трёх чисел.

Первые два числа нормально преобразовались, а вот третье число преобразовалось в строку в странном виде (на самом деле это научное представление числа). И это может источником проблемы при передаче строки куда-нибудь, например, на сервер. Если сервер не ожидает от вас такой подлости, то будет генерировать ошибки из-за странной записи. Нужно найти другие способы конвертации.

Последний пример самый подходящий для нас, но вам нужно знать, сколько знаков идёт после десятичной точки. Остальные два пригодятся, если число можно округлить.

Символы (тип char)

Из примера выше видно, что переменной можно присвоить код символа или непосредственно сам символ, который следует окружить одинарными кавычками. Попробуйте запустить пример и посмотреть, какое слово получится из трёх указанных символов.

Не следует путать символ ‘a’ со строкой «a», состоящей из одного символа. На экране монитора они выглядят одинаково, но в программах ведут себя по разному.

Хотя тип char используется для хранения Unicode-символов, его можно использовать как целочисленный тип, используя сложение или вычитание.

В результате получим:

Если вы думаете, что увеличив значение переменной ch1 ещё на одну единицу, получите символ «й», то глубоко заблуждаетесь.

Чтобы узнать, какой символ содержится в значении переменной, заданной как int, можно воспользоваться двумя специальными методами из класса EncodingUtils:

Для стандартных символов ASCII:

Для расширенной таблицы символов:

Методы работают со строками, но если мы используем строку из одного символа, то получим то, что нам нужно.

В упрощённом виде, если работаем со стандартными символами ASCII (on 0 до 127), то можно получить символ из int ещё проще.

Класс Character

Класс Character является оболочкой вокруг типа char. Чтобы получить значение типа char, содержащее в объекте класса Character, вызовите метод charValue().

С классом Character редко имеют дело в Android, но помните, что класс содержит огромное количество констант и методов. Например, можно определить, является ли символ цифрой или буквой, или написан ли символ в нижнем или в верхнем регистре.

Булевы значения

Тип boolean предназначен для хранения логических значений и может принимать только одно из двух возможных значений: true или false. Данный тип всегда возвращается при использовании операторов сравнения (больше, меньше, равно, больше или равно, меньше или равно, не равно). Также он используется в управляющих операторах if и for.

В отличие от реальной жизни, где вполне может состояться диалог:

В операторах if используется укороченная запись при значении true:

Java сам поймёт, что переменную check нужно сравнить с true.

Класс Boolean

Ещё один совет, применимый ко всем типам. Допустим, нам нужно объявить 32 переменных типа boolean:

Умножаем 4 байта на 32 переменных и получаем 128 байт занятой памяти. А если объявим массив:

Считаем: 4 + 8 + 8 + 32 * 1 = 52. С учётом выравнивания памяти по 8 байт, получаем не 52, а 56. Всё равно меньше, чем в первом примере.

Конвертируем строку в булево значение.

Конвертируем булево значение в строку.

Приведение типов

Когда мы производим какие-то действия с переменными, то нужно следить за типами. Нельзя умножать котов на футбольные мячи, это противоречит здравому смыслу. Также и с переменными. Если вы присваиваете переменной одного типа значение другого типа, то вспоминайте теорию. Например, вы без проблем можете присвоить значение типа int переменной типа long, так как все числа из диапазона типа int гарантировано помещаются в диапазон чисел long. В этом случае Java выполнит преобразование автоматически, вы даже ничего не заметите.

Читайте также:  о чем говорит повышенное содержание сои в крови

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

Таблица выглядит следующим образом.

Сплошные линии обозначают преобразования, выполняемые без потери данных. Штриховые линии говорят о том, что при преобразовании может произойти потеря точности.

Типы целых чисел и чисел с плавающей точкой совместимы частично. Например, число 5 вполне может быть числом с плавающей точкой (5.0).

Совсем не совместимы, например, char и boolean.

С автоматическим приведением мы разобрались. Рассмотрим вариант, когда нужно преобразовать число типа int в число типа byte. Преобразование автоматически невозможно, поскольку byte меньше int. Но, например, число 99 вполне можно использовать и как int и как byte. В этом случае используется явное приведение типов, то есть преобразование из одного типа в другой (преобразование с сужением).

Выглядит это следующим образом:

Как видите, вы в скобках указываете тип, к которому нужно явно привести переменную.

Существует ещё вариант приведения с усечением. Это когда число с плавающей точкой приводится к целочисленному типу. В этом случае отбрасывается дробная часть (хвост). Например, число 3.14 будет усечено до числа 3:

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

Например, попробуйте преобразовать число 454.874 в тип byte:

Рассмотрим такой пример. Допустим у нас есть выражение, где промежуточное значение может выходить за пределы допустимого диапазона:

При умножении переменных a * b промежуточный результат вышел за пределы диапазона допустимых значений для типов byte. Java во время вычисления промежуточных результатов автоматически повышает тип каждого операнда до int и ошибки не происходит.

Это удобно, но может поставить в тупик в следующем примере:

С виду всё правильно. Если не слишком больше число типа byte, а итоговый результат тоже не выходит за диапазон допустимых значений. Но Java не позволит вам написать подобный код. Происходит следующее. Во время вычисления выражения тип операндов был автоматически повышен до int, как об этом говорилось выше. При этом тип результата тоже был повышен до int. Получается, что результат вычисления равен типу int, а мы пытаемся его присвоить переменной b, которая у нас объявлена как byte. И это несмотря на то, что итоговый результат может быть типом byte. Как же выйти из этого положения? Следует использовать явное приведение типов:

Мы рассмотрели единичные примеры. Пора обобщить и запомнить несколько правил.

Типы всех значений byte, short, char повышаются до типа int, как это было рассмотрено выше.

Если один операнд имеет тип long, то тип всего выражения повышается до long.

Если один операнд имеет тип float, то тип всего выражения повышается до float.

Если один операнд имеет тип double, то тип всего выражения повышается до double.

В первом промежуточном выражении (f * b) тип переменной b повышается до float и промежуточный результат также становится float. В следующем выражении (i / c) тип у переменной c повышается до int и промежуточный результат также становится типом int. В выражении (d * s) тип переменной s повышается до double и промежуточное выражение также становится double. В результате у нас появились три промежуточные значения типов: float, int, double. При сложении float и int мы получаем float, затем при вычитании с использованием float и double тип повышается до double, который и становится окончательным типом результата выражения.

Источник

Pro Java

Страницы

13 апр. 2015 г.

Особенности типа char мы рассмотрели в предыдущей статье. Здесь же мы рассмотрим все целочисленные примитивные типы Java оптом, так как они отличаются друг от друга только размером, а следовательно, только максимальным и минимальным значениями, которые могут содержать. Все типы за исключением char являются знаковыми, char, как уже объяснялось без знаковый. Повторим таблицу размеров и значений для этих типов тут еще раз:

Целочисленные литералы

Значения целочисленным переменным и константам задаются при помощи следующих литералов:

108 – десятичный литерал
0154 – восьмеричный литерал (в начале стоит ноль)
0x6c – шестнадцатеричный литерал
0b01101100 – двоичный литерал (с Java 7)

Так же в числовых литералах можно использовать символ подчеркивания _ для разграничения разрядов, это сделано только для удобства написания и понимания и ни как не влияет на значение (с Java 7). Например:

0110_1100, 0x7fff_ffff, 0177_7777_7777

Для обозначения литерала типа long можно использовать суффикс L (можно использовать и маленькую l, но ее легко попутать с единицей 1). Например:

3_000_000_000L

В связи с этим есть один интересный момент, что переменной типа long не возможно задать значения больше 2147483647 следующим оператором присваивания:

long iLong = 2147483648 ;

Хотя значение 2147483648 является допустимым для типа long, но компилятор считает это число 2147483648 литералом типа int, поскольку у него нет суффикса L, а для типа int число 2147483648 является не допустимым значением и поэтому компилятор выдаст ошибку. Чтобы этого не было надо использовать суффикс L. Например:

long iLong = 2147483648L ;

Такое выражение компилятор уже примет как правильное.

Над целочисленными типами можно совершать различные операции при помощи операторов сравнения, математических операторов и операторов побитового сдвига.

Операции сравнения для примитивных типов вообще и для целочисленных в частности сравнивают их значения. Операторы сравнения мы уже рассматривали при изучении типа boolean. Результатом этих операций может быть только значение типа boolean.

Арифметические операции

Тут впрочем все просто. На что только надо обратить внимание это то, что деление над целочисленными типами тоже целочисленное и в результате этих операций можно получить как целое число или целую или дробную часть от операции совершенной соответствующими операторами. Инкремент и декремент (увеличение или уменьшение на единицу) может быть как префиксным, так и постфиксным. При использовании префиксного оператора сперва происходит инкремент иди декремент переменной, а затем используется ее значение, при постфиксной наоборот – сперва используется текущее значение переменной, а затем происходит ее декремент или инкремент.

Все это мы подробно рассмотрим на практических примерах.

Операция деление по модулю (или остаток) определяется так:
a % b = a — (a / b) * b

То есть 5%3=2, потому что 5-(5/3)*3=2, имейте в виду что 5/3 в данном случае это целочисленное деление и результат этой операции равен 1.

Все операции кроме инкремента и декремента имеют короткую форму записи, представленную в левой колонке. С подобным мы уже сталкивались в типе boolean.

Ну а теперь, чтобы не было скучно, простенький пример на пройденную тему.

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

Читайте также:  когда можно обрезать пионы после цветения на зиму стебли

Если не понятно то в двух словах объясню. Максимальное положительное значение переменной типа byte равно 127. Что мы и задали в строке 32. Затем чтобы обмануть компилятор мы два раза сделали инкремент этого значения, то есть по идее должны были получить число 129. Если бы мы просто попытались сделать c=c+2, то компилятор и IDE показали бы нам ошибку приведения типов (можете попробовать и убедиться). Далее мы вывели получившиеся значение, которое стало равно –127. Это произошло потому, что в старший разряд (первый слева) была помещена единица. Числу 129 соответствует двоичное значение 1000 0001.

Но для типа byte, максимальным положительным значением является 127, что соответствует двоичному числу 0111 1111. Когда в старший разряд помещается единица, то это число начинает интерпретироваться как отрицательное. То есть если двоичное число 1000 0001 интерпретировать как отрицательное, то его десятичное значение будет равно –127. Почему так?

Теперь приведу вывод этой программы:

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

Побитовые операции в ряде случаев вещь чрезвычайно полезная и нужная.

В данном примере я рассмотрел из совмещенных операций только операции совмещенного сложения и присвоения, а так же вычитания и присвоения (строки 28 и 30), умножение, деление и деление по модулю уже не стал кодить, так как там все аналогично.

Про операцию деления по модулю еще стоит отметить одно правило:

a == (a / b) * b + (a % b)

Это так на заметку. Ну и поперли дальше!

Побитовые операции

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

Арифметический сдвиг влево бывает только один, так как там только один вариант чем заполнять младшие освободившиеся биты – это ноль.

Особенно осторожным надо быть с логическим сдвигом вправо >>>.

Теперь рассмотрим все эти операторы более подробно.

Побитовое НЕ (

является оператором побитового отрицания, или побитового НЕ. Он инвертирует каждый бит своего единственного операнда, преобразовывая единицы в нули и нули в единицы. Например:

Побитовое И (&)

Этот оператор объединяет два целых операнда посредством логической операции И с их отдельными битами. В результате биты устанавливаются в единицу только там, где соответствующие биты установлены в единицу в обоих операндах. Например:

Побитовое ИЛИ (|)

Этот оператор объединяет два целых операнда посредством логической операции ИЛИ с их отдельными битами. В результате биты устанавливаются в единицу только там, где соответствующие биты установлены в единицу в одном или обоих операндах. Если оба соответствующих бита в операндах равны нулю, то результат содержит нулевой бит. Например:

Побитовое исключающее ИЛИ (^)

Этот оператор объединяет два целых операнда посредством логической операции
исключающего ИЛИ с их отдельными битами. В результате биты установлены в единицу только там, где соответствующие биты в двух операндах различны. Если оба бита – нули или единицы, то результат будет содержать нулевой бит. Например:

Если левый операнд представляет тип long, то значение правого операнда должно находиться в диапазоне между 0 и 63. В противном случае левый операнд считается int, а значение правого операнда должно располагаться между 0 и 31.

Побитовый арифметический сдвиг вправо со знаком (>>)

Побитовый логический сдвиг вправо без знака (>>>)

Этот оператор аналогичен оператору >>, но он всегда заполняет нулями старшие биты, каким бы ни был знак левого операнда. Данный прием называется дополнением нулями. Его применяют, если левый операнд интерпретируется как значение без знака (несмотря на то что в Java все типы со знаком). Например:

Как я уже говорил, с этим оператором надо быть очень осторожным, так как надо учитывать, что его операнды автоматически приводятся к типу int (или long), то есть их разрядность увеличивается. Приведенный пример справедлив для типа данных int, а вот для byte и short, он уже может подглючить. Поэтому пример с логическим сдвигом вправо мы рассмотрим более подробно, отдельно от остальных.

И еще несколько небольших замечаний:

Ну а теперь немножко практики.

В библиотеку ProJava.jar я добавил еще парочку статических методов printlnByte и printByte для вывода значений типа byte в двоичном виде как строку.

И далее то что это программа выводит

Тут все более или менее просто и понятно. Далее будем разбираться с оператором логического сдвига вправо.

Теперь посмотрим на вывод этой программы:

39 строка, которая выводит двоичное значение переменной типа byte b1 тоже преподнесла нам сюрприз. По идее в двух старших битах должны быть два нуля, но мы их там не наблюдаем. Там пара единиц. Это опять же произошло все по той же причине автоматического расширение byte и short до int или long, если long присутствует в выражении.

Приведение типов, явное и неявное мы рассмотрим чуток позже, а пока полезно знать о граблях неявного приведения типов.

И так в строке 39 мы просто получили обрубок значения int, старшие разряды которого были выкинуты, вместе с двумя нулями в начале (смотрите внимательно скриншот вывода).

Теперь поправим эту ситуацию, чтобы все работало правильно. Для этого надо применить маску 0xff, которая превратит все старшие 24 разряда типа int в нули.

и далее вывод программы (только новая часть):

Ну и напоследок приведу табличку побитовых операций (не сдвиговых, т.к. это не имеет смысла)

В принципе это тема весьма нужная и полезная и развлекаться с примерами здесь можно очень долго, но нам надо двигаться вперед.

А теперь, чтобы стало понятнее рассмотрим это на примере:

И вывод этой программы на консоль:

Как видим, там где мы сдвигали на 32 разряда, ни какого сдвига на самом деле не произошло по описанной выше причине.

Кроме того, при сдвиге на 48 позиций вправо, сдвиг на самом деле произошел на 16 позиций, по той же причине.

То есть можно заключить, что двигать переменную на количество бит равное или большее ее ширине в битах просто не имеет смысла, так как в этом случае сдвига или вовсе не будет или же будет на количество бит равное делению по модулю количества сдвигаемых бит, на ширину сдвигаемого типа.

Источник

Строительный портал