Диапазон инт

Диапазон инт Анемометр

Диапазон инт

Диапазон инт

Вступление

Разработку приложений можно рассматривать как работу с некоторыми данными, а точнее — их хранение и обработку. Сегодня хотелось бы затронуть первый ключевой аспект. Как данные хранятся в Java? Тут у нас есть два возможные формата: ссылочный и примитивный тип данных.

Давайте поговорим о видах примитивных типов и возможностях работы с ними (как ни крути, это фундамент наших знаний языка программирования).

Примитивные типы данных Java — это основа, на которой держится всё. Нет, я нисколько не преувеличиваю. У Oracle примитивам посвящён отдельный Tutorial: Primitive Data Types

Диапазон инт

Немного истории. Вначале был ноль. Но ноль — это скучно. И тогда появился bit (бит). Почему его так назвали? Назвали его так от сокращения “bit

” (двоичное число). То есть у него есть только два значения. А так как был ноль, то логично, что теперь стало или 0 или 1. И стало жить веселее.

Биты начали собираться в стаи. И эти стаи стали называть byte (байт). В современном мире byte = 2 в третьей степени, т.е. 8. Но, оказывается, так было не всегда. Существует множество догадок, легенд и слухов, откуда пошло название byte. Кто-то считает, что всё дело в кодировках того времени, а кто-то считает, что так было выгоднее считать информацию. Байт — это наименьшая адресуемая часть памяти. Именно байты имеют уникальные адреса в памяти.

Есть легенда о том, что ByTe это сокращение от Binary Term — машинное слово. Машинное слово – если говорить просто, это количество данных, которые процессор может обработать за одну операцию. Раньше размер машинного слова совпадал с наименьшей адресуемой памятью.

В Java, переменные могут хранить только значение байтов. Как я и говорил выше, в Java существует два вида переменных:

В данном разделе будут рассмотрены основные типы данных в С++, эти типы данных ещё называются встроенными. Язык программирования С++ является расширяемым языком программирования. Понятие расширяемый означает то, что кроме встроенных типов данных, можно создавать свои типы данных. Поэтому в С++ существует огромное количество типов данных. Мы будем изучать только основные из них.

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

Тип данных bool

Первый в таблице — это тип данных bool — целочисленный тип данных, так как диапазон допустимых значений — целые числа от 0 до 255. Но как Вы уже заметили, в круглых скобочках написано — логический тип данных, и это тоже верно. Так как bool используется исключительно для хранения результатов логических выражений. У логического выражения может быть один из двух результатов true или false. true — если логическое выражение истинно, false — если логическое выражение ложно.

Но так как диапазон допустимых значений типа данных bool от 0 до 255, то необходимо было как-то сопоставить данный диапазон с определёнными в языке программирования логическими константами true и false. Таким образом, константе true эквивалентны все числа от 1 до 255 включительно, тогда как константе false эквивалентно только одно целое число — 0.  Рассмотрим программу с использованием типа данных bool.

строке 9 объявлена переменная типа bool, которая инициализирована значением 25. Теоретически после строки 9, в переменной boolean должно содержаться число 25, но на самом деле в этой переменной содержится число 1. Как я уже говорил, число 0 — это ложное значение, число 1 — это истинное значение. Суть в том, что в переменной типа bool могут содержаться два значения — 0 (ложь) или 1 (истина). Тогда как под тип данных bool отводится целый байт, а это значит, что переменная типа bool может содержать числа от 0 до 255. Для определения ложного и истинного значений необходимо всего два значения 0 и 1. Возникает вопрос: «Для чего остальные 253 значения?».

Исходя из этой ситуации, договорились использовать числа от 2 до 255 как эквивалент числу 1, то есть истина. Вот именно по этому в переменной boolean содержится число 25 а не 1. В строках 10 -13 объявлен оператор условного выбора if, который передает управление оператору в строке 11, если условие истинно, и оператору в строке 13, если условие ложно. Результат работы программы смотреть на рисунке 1.

true = 1
Для продолжения нажмите любую клавишу . . .

Рисунок 1 — Тип данных bool

Тип int

Если вы хотите хранить в переменных , вам нужно использовать тип .

— это сокращение от  ( с английского), что как бы намекает, что этот тип позволяет хранить .

Переменные типа способны хранить в диапазоне от 2 миллиарда до 2 миллиарда. Или, если быть более точным, то от 2,147,483,648 до 2,147,483,647.

Такие некруглые значения связаны с устройством памяти компьютера.

В Java для типа int выделено памяти. Каждый байт памяти состоит из . Каждый бит может принимать только 2 значения — 0 или 1. Переменная типа int содержит и может принимать 4,294,967,296 значений.

Половину этого диапазона отдали под отрицательные числа, а вторую — под положительные. Вот и получилось как раз от 2,147,483,648 до 2,147,483,647.

Вещественные типы

Среди примитивных типов также есть два вещественных. Хотя это не совсем точное название. Официально они называются числа с плавающей точкой — floating point numbers. Название происходит из стандарта, когда целую и дробную часть числа разделяет точка (а не запятая).

В каждой стране свои стандарты для записи чисел (внезапно!).

Многие из нас привыкли писать точки для разделения тысяч и запятую для отделения дробной части: например, миллион целых и 153 тысячных мы бы записали так 1.000.000,153. А вот в США, где жили создатели Java, принят другой стандарт: 1,000,000.153

В Java есть два примитивных типа с плавающей точкой: double и float.

Как мы уже говорили ранее, эти типы внутри устроены специфическим образом: фактически внутри каждой переменной этих типов находится не одно число, а два:

Например, дробное число 987654.321 можно представить как 0.*10. Поэтому в памяти оно будет представлено как два числа ( — значащая часть числа) и ( — степень десятки)

Само название типа float происходит от ing point number. Размер этого типа совсем небольшой — всего 4 байта (32 бита), но он может хранить значения от -3.4*1038 до 3.4*1038. Под мантиссу отдается 24 бита, под экспоненту — 8 бит. Этот тип способен хранить всего 8 значащих цифр.

Такой подход позволяет хранить гораздо большие числа, чем int, используя все те же 4 байта. Но при этом мы жертвуем точностью. Часть памяти расходуется на хранение мантиссы, поэтому такие числа хранят всего 6-7 знаков после запятой, остальные отбрасываются.

Как видите, основной недостаток этого типа — очень маленькое количество значащих цифр и потеря точности уже в восьмой цифре. Поэтому тип float не сильно популярен среди Java-программистов.

Тип double является стандартным типом с плавающей точкой. Его название происходит от double floating point. Его еще называют числом с плавающей точкой . Все вещественные литералы по умолчанию имеют тип double.

Этот тип занимает 8 байт памяти (64 бита) и может хранить значения от -1.7*10308 до 1.7*10308. Важным моментом является то, что под его мантиссу отводится 53 бита, а остальные 11 – под экспоненту.

Это позволяет хранить 15-17 значащих цифр.

Такая точность, особенно в сравнении с типом float, является определяющей: 99% всех операций с вещественными числами выполняются с типом double.

Под экспоненту выделяется 11 бит, что позволяет хранить степень десятки от -323 до +308 (степень двойки — от -1024 до +1023). Тип double легко может хранить число с сотней нулей после запятой:

Тип boolean

И последний примитивный тип — это boolean.

Как вы уже знаете, он может принимать только два значения: и .

Собственно, все, что можно знать об этом типе, вы уже знаете.

Целочисленные типы данных

Целочисленные типы данных используются для представления чисел. В таблице 1 их аж шесть штук: short int, unsigned short int, int, unsigned int, long int, unsigned long int. Все они имеют свой собственный размер занимаемой памяти и  диапазоном принимаемых значений. В зависимости от компилятора, размер занимаемой памяти и диапазон принимаемых значений могут изменяться. В таблице 1 все диапазоны принимаемых значений и размеры занимаемой памяти взяты для компилятора MVS2010. Причём все типы данных в таблице 1 расположены в порядке возрастания размера занимаемой памяти и диапазона принимаемых значений. Диапазон принимаемых значений, так или иначе, зависит от размера занимаемой памяти. Соответственно, чем больше размер занимаемой памяти, тем больше диапазон принимаемых значений. Также диапазон принимаемых значений меняется в случае, если тип данных объявляется с приставкой unsigned — без знака. Приставка unsigned говорит о том, что тип данных не может хранить знаковые значения, тогда и диапазон положительных значений увеличивается в два раза, например, типы данных short int и unsigned short int.

Приставки целочисленных типов данных

short — приставка укорачивает тип данных, к которому применяется, путём уменьшения размера занимаемой памяти;

long — приставка удлиняет тип данных, к которому применяется, путём увеличения размера занимаемой памяти;

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

Так, что, по сути, мы имеем один целочисленный тип для представления целых чисел — это тип данных int. Благодаря приставкам short, long, unsigned появляется некоторое разнообразие типов данных int, различающихся размером занимаемой памяти и (или) диапазоном принимаемых значений.

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

В С++ существуют два типа данных с плавающей точкой: float и double. Типы данных с плавающей точкой предназначены для хранения чисел с плавающей точкой. Типы данных float и double могут хранить как положительные, так и отрицательные числа с плавающей точкой. У типа данных float размер занимаемой памяти в два раза меньше, чем у типа данных double, а значит и диапазон принимаемых значений тоже меньше. Если тип данных float объявить с приставкой long, то диапазон принимаемых значений станет равен диапазону принимаемых значений типа данных double. В основном, типы данных с плавающей точкой нужны для решения задач с высокой точностью вычислений, например, операции с деньгами.

Итак, мы рассмотрели главные моменты, касающиеся основных типов данных в С++. Осталось только показать, откуда взялись все эти диапазоны принимаемых значений и размеры занимаемой памяти. А для этого разработаем программу, которая будет вычислять основные характеристики всех, выше рассмотренных, типов данных.

max_val_type = 2^(b * 8 – 1) – 1; // для типов данных с отрицательными и положительными числами
// где, b – количество байт выделяемое в памяти под переменную с таким типом данных
// умножаем на 8, так как в одном байте 8 бит
// вычитаем 1 в скобочках, так как диапазон чисел надо разделить надвое для положительных и отрицательных значений
// вычитаем 1 в конце, так как диапазон чисел начинается с нуля

// типы данных с приставкой unsigned
max_val_type = 2^(b * 8 ) – 1; // для типов данных только с положительными числами
// пояснения к формуле аналогичные, только в скобочка не вычитается единица

Пример работы программы можно увидеть на рисунке 3. В первом столбце показаны основные типы данных в С++, во втором столбце размер памяти, отводимый под каждый тип данных и в третьем столбце — максимальное значение, которое может содержать соответствующий тип данных. Минимальное значение находится аналогично максимальному. В типах данных с приставкой unsigned минимальное значение равно 0.

data type byte max value
bool = 1 255.00
char = 1 255.00
short int = 2 32767.00
unsigned short int = 2 65535.00
int = 4 2147483647.00
unsigned int = 4 4294967295.00
long int = 4 2147483647.00
unsigned long int = 4 4294967295.00
float = 4 2147483647.00
double = 8 9223372036854775808.00
Для продолжения нажмите любую клавишу . . .

Рисунок 3 — Типы данных С++

Если, например, переменной типа short int присвоить значение 33000, то произойдет переполнение разрядной сетки, так как максимальное значение в переменной типа short int  это 32767. То есть в переменной типа short int сохранится какое-то другое значение, скорее всего будет отрицательным. Раз уж мы затронули тип данных int, стоит отметить, что можно опускать ключевое слово int и писать, например, просто short. Компилятор будет интерпретировать такую запись как short int. Тоже самое относится и к приставкам long и unsigned. Например:

// сокращённая запись типа данных int
short a1; // тоже самое, что и short int
long a1; // тоже самое, что и long int
unsigned a1; // тоже самое, что и unsigned int
unsigned short a1; // тоже самое, что и unsigned short int

Краткая запись создания переменных

Если в одном месте программы нужно создать много переменных одного типа, это можно сделать, используя сокращенную запись:

Краткая запись создания нескольких переменных одного типа

Создание переменной типа int

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

Объявление переменной типа int

Где имя — это имя переменной. Примеры:

Размер (регистр) букв имеет значение: команды int olor и int olor объявят две переменные.

Команды же Color и COLOR компилятор вообще и сообщит об ошибке. int — это специальное слово, обозначающее целый тип, и пишется оно только строчными буквами.

Тип данных char

ASCII ( от англ. American Standard Code for Information Interchange) — американский стандартный код для обмена информацией.

Рассмотрим программу с использованием типа данных char.

строке 9 объявлена переменная с именем symbol, ей присвоено значение символа ‘a’ASCII кодстроке 10 cout печатает символ, содержащийся в переменной symbolстроке 11 объявлен строковый массив с именем string, причём размер массива задан неявно. В строковый массив сохранена строка “cppstudio.com”. Обратите внимание на то, что, когда мы сохраняли символ в переменную типа char, то после знака равно мы ставили одинарные кавычки, в которых и записывали символ. При инициализации строкового массива некоторой строкой, после знака равно ставятся двойные кавычки, в которых и записывается некоторая строка. Как и обычный символ, строки выводятся с помощью оператора coutстрока 12. Результат работы программы показан на рисунке 2.

symbol = a
string = cppstudio.com
Для продолжения нажмите любую клавишу . . .

Рисунок 2 — Тип данных char

Бесконечность

Числа с плавающей точкой обладают еще одной интересной особенностью: они позволяют хранить специальное значение, обозначающее бесконечность. Причем может быть положительная бесконечность и отрицательная бесконечность.

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

Не число (NaN)

Любые операции с бесконечностью дают бесконечность. В целом да, но не все.

Числа с плавающей точкой могут хранить еще одно специальное значение — . Это сокращение от ot umber (не число).

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

Ну, а в Java, если разделить бесконечность на бесконечность, будет NaN.

Любая операция с NaN дает NaN.

Java byte

Итак, история подарила нам байт – минимальный объём памяти, который мы можем использовать. И состоит он из 8 бит. Самый маленький целый тип данных в java – byte. Это знаковый 8-битовый тип. Что это значит?

Давайте считать. 2 ^ 8 будет 256. Но что же делать, если мы хотим отрицательное число? И решили разработчики Java, что двоичный код «10000000» будет обозначать -128, то есть старший бит (самый левый бит) будет обозначать, отрицательное ли число. Двоичное «0111 1111» равняется 127. То есть 128 никак не обозначить, т.к. это будет -128.

Полный расчёт приведён в этом ответе: Why is the range of bytes -128 to 127 in Java?

Чтобы понять как получаются числа, стоит посмотреть на картинку:

Диапазон инт

Соответственно, чтобы вычислить размер 2^(8-1) = 128. Значит минимальная граница (а она с минусом) будет -128. А максимальная 128 – 1 (вычитаем ноль). То есть максимум будет 127.

На самом деле, с типом byte работаем мы не так часто на “высоком уровне”. В основном это обработка «сырых» данных. Например, при работе с передачей данных по сети, когда данные это набор 0 и 1, переданных через какой-то канал связи. Или при чтении данных из файлов. Так же могут быть использованы при работе со строкам и кодировками.

Пример кода:

Кстати, не стоит думать, что использование типа byte будет снижать потребление памяти. В основном byte используется для уменьшения расхода памяти при хранении данных в массивах (например, хранение данных, полученных по сети в некотором буфере, который будет реализован в виде массива байт).
А вот при операциях над данными использование byte не оправдает ваши ожидания.

Связано это с реализацией Java Virtual Machine (JVM). Так как большинство систем 32 или 64 разрядные, то byte и short при вычислениях будут приведены к 32-битному int, о котором мы поговорим дальше. Так проще производить вычисления. Подробнее см. Is addition of byte converts to int because of java language rules or because of jvm?. В ответе даны так же ссылки на JLS (Java Language Specification).

Кроме того, использование byte в неправильном месте может привести к неловким моментам:

Тут будет зацикливание. Потому что значение счётчика дойдёт до максимума (127), произойдёт переполнение и значение станет -128. И мы никогда не выйдем из цикла.

Short

Лимит значений из byte довольно мал. Поэтому, для следующего типа данных решили увеличить количество бит вдвое. То есть теперь не 8 бит, а 16. То есть 2 байта.

Значения можно посчитать так же. 2^(16-1) = 2 ^ 15 = 32768. Значит, диапазон от -32768 до 32767. Используют его совсем редко для каких-либо специальных случаев. Как говорит нам документация языка Java: «you can use a short to save memory in large arrays».

Вот мы и добрались до самого частоиспользуемого типа. Занимает он 32 бита, или 4 байта. В общем, мы продолжаем удваивать.
Диапазон значений от -2^31 до 2^31 – 1.

Максимальное значение int

Максимальное значение int 2147483648 – 1, что совсем не мало. Как выше было указано, для оптимизации вычислений, т.к. современным компьютерам с учетом их разрядности удобнее считать, данные могут быть неявно преобразованы к int. Вот простой пример:

byte a = 1;
byte b = 2;
byte result = a + b;

Такой безобидный код, а мы получим ошибку: «error: incompatible types: possible lossy conversion from int to byte». Придётся исправить на byte result = (byte)(a + b);

И ещё один безобидный пример. Что будет если запустим следующий код?

int value = 4;
System.out.println(8/value);
System.out.println(9/value);
System.out.println(10/value);
System.out.println(11/value);

А мы получим вывод

Дело обстоит в том, что при работе с int значениями остаток отбрасывается, оставляя только целую часть(в таких случая лучше уж использовать double).

Long

Продолжаем удваивать. 32 умножаем на 2 и получаем 64 бита. По традиции, это 4 * 2, то есть 8 байт. Диапазон значений от -2^63 до 2^63 – 1. Более чем достаточно. Данный тип позволяет считать большие-большие числа. Часто используется при работе со временем. Или с большими расстояниями, например.

Для обозначения того, что число это long после числа ставят литерал L – Long. Пример:

long longValue = 4;
longValue = 1l; // Не ошибка, но плохо читается
longValue = 2L; // Идеально

Хочется забежать вперёд. Далее мы будем рассматривать тот факт, что для примитивов есть соответствующие обёртки, которые дают возможность работать с примитивами как с объектами. Но есть интересная особенность. Вот пример:

На том же Tutorialspoint online compiler можете проверить такой вот код:

Данный код работает без ошибок, всё хорошо. Но стоит в методе printLong заменить тип с long на Long (т.е. тип становится не примитивным, а объектным), как становится джаве непонятно, какой параметр мы передаём. Она начинает считать, что передаётся int и будет ошибка. Поэтому, в случае с методом необходимо будет явно указывать 4L.

Очень часто long используется как ID при работе с базами данных.

Java float и Java double

Данные типы называются типами с плавающей точкой. То есть это не целочисленные типы. Тип float является 32битным (как int), а double называется типом с двойной точностью, поэтому он 64битный (умножаем на 2, всё как мы любим).

Пример:

А вот пример разницы значений (из-за точности типов):

Данные примитивные типы используются в математике, например. Вот доказательство, константа для вычисления числа PI. Ну и вообще можно посмотреть API класса Math.

Вот что ещё должно быть важно и интересно: даже в документации сказано: «This data type should never be used for precise values, such as currency. For that, you will need to use the java.math.BigDecimal class instead.Numbers and Strings covers BigDecimal and other useful classes provided by the Java platform.». То есть деньги в float и double не надо вычислять.

Пример про точность на примере работы в NASA: Java BigDecimal, Dealing with high precision calculations

Ну и чтобы самим прочувствовать:

Выполните этот пример, а потом добавьте 0 перед цифрами 5 и 4. И вы увидите весь ужас)

Есть интересный доклад на русском про float и double в тему: https://youtu.be/1RCn5ruN1fk

Примеры работы с BigDecimal можно увидеть здесь: Make cents with BigDecimal

Кстати, float и double могут вернуть не только число. Например, пример ниже вернёт Infinity (т.е. бесконечность):

А этот вернёт NAN:

Про бесконечность понятно. А что такое NaN? Это Not a number, то есть результат не может быть высчитан и не является числом. Вот пример:

Мы хотим вычислить квадратный корень из -4. Квадратный корень из 4 это 2. То есть 2 надо возвести квадрат и тогда мы получим 4. А что надо возвести в квадрат, чтобы получить -4? Не получится, т.к. если положительное число будет, то оно и останется. А если было отрицательное, то минус на минус даст плюс. То есть это не вычисляемо.

Вот ещё отличный обзор на тему чисел с плавающей точкой: Где ваша точка?

Java boolean

Следующий тип – булевский (логический тип). Он может принимать значения только true или false, которые являются ключевыми словами.

Используется в логических операциях, таких как циклы while, и в ветвлении при помощи if, switch.

Что тут можно интересного узнать? Ну, например, теоретически, нам достаточно 1 бита информации, 0 или 1, то есть true или false. Но на самом деле Boolean будет занимать больше памяти и это будет зависеть от конкретной реализации JVM. Обычно на это тратится столько же, сколько на int. Как вариант – использовать BitSet.

Вот краткое описание из книги «Основы Java»: BitSet

Java char

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

Итак, данные в char занимают 16 бит и описывают символ. В Java для char используется кодировка Unicode.

Символ можно задать в соответствии с двумя таблицами (посмотреть можно тут):

Диапазон инт

Пример в студию:

Кстати, char, являясь по своей сути всё таки числом, поддерживает математические действия, такие как сумма. А иногда это может привести к забавным последствиям:

Настоятельно советую проверить в онлайн IDE от tutorialspoint. Когда я увидел этот пазлер на одной из конференций мне это подняло настроение. Надеюсь, Вам пример тоже понравится)

UPDATED: Это было на Joker 2017, доклад: “Java Puzzlers NG S03 — Откуда вы все лезете-то?!”.

Литералы

Литерал – явно заданное значение. При помощи литералов можно указывать значения в разных системах счисления:

На восьмеричной системе я бы чуть подробнее остановился, потому что это забавно:

int costInDollars = 08;

Эта строчка кода не скомпилируется:

error: integer number too large: 08

Кажется, что за бред. А теперь вспомним про двоичную и восьмеричную системы. В двоичной системе нет двойки, т.к. есть два значения (начиная с 0). А восьмеричной системе есть 8 значений, начиная с нуля. То есть самого значения 8 нет. Поэтому и ошибка, которая на первый взгляд кажется абсурдной. И чтобы вспомнить вот «вдогонку» правила перевода значений:

Диапазон инт

Классы-обертки

Примитивы в Java имеют свои классы-обертки, чтобы можно было работать с ними как с объектами. То есть, для каждого примитивного типа существует, соответствующий ему ссылочный тип.

Диапазон инт

Классы-обертки являются immutable (неизменяемыми): это означает, что после создания объекта его состояние — значение поля value — не может быть изменено. Классы-обертки задекларированы как final: объекты, так сказать, read-only.

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

Java автоматически делает преобразования между примитивными типами и их обертками:

Integer x = 9; // autoboxing
int n = new Integer(3); // unboxing

В основном пакете, java.lang, уже есть реализации классы Boolean, Byte, Short, Character, Integer, Float, Long, Double, и нам не нужно ничего городить своего, а только переиспользовать готовое.

К примеру, такие классы дают нам возможность создать, скажем, List

, ведь List должен содержать только объекты, чем примитивы не являются.

Для преобразования значения примитивного типа есть статические методы valueOf, например, Integer.valueOf(4) вернёт объект типа Integer. Для обратного преобразования есть методы intValue(), longValue() и т. п.

Компилятор вставляет вызовы valueOf и *Value самостоятельно, это и есть суть autoboxing и autounboxing.

Как выглядит пример автоупаковки и автораспаковки, представленный выше, на самом деле:

Integer x = Integer.valueOf(9);
int n = new Integer(3).intValue();

Подробнее про автоупаковку и автораспаковку можно почитать вот в этой статье.

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

При работе с примитивами существует такое понятие как приведение типов, одно из не очень приятных свойств C++, тем не менее приведение типов сохранено и в языке Java.

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

Существует преобразование с расширением и преобразование сужающее. Всё на самом деле просто. Если тип данных становится больше (допустим, был int, а стал long), то тип становится шире (из 32 бит становится 64). И в этом случае мы не рискуем потерять данные, т.к. если влезло в int, то в long влезет тем более, поэтому данное приведение мы не замечаем, так как оно осуществляется автоматически. А вот в обратную сторону преобразование требует явного указания от нас, данное приведение типа называется — сужение. Так сказать, чтобы мы сами сказали: «Да, я даю себе отчёт в этом. В случае чего — виноват сам».

Чтобы потом в таком случае не говорили что «Ваша Джава плохая», когда получат внезапно -128 вместо 128 ) Мы ведь помним, что в байте 127 верхнее значение и всё что находилось выше него соответственно можно потерять. Когда мы явно превратили наш int в байт, то произошло переполнение и значение стало -128.

Область видимости

Это то место в коде, где данная переменная будет выполнять свои функции и хранить в себе какое-то значение. Когда же эта область закончится, переменная перестанет существовать и будет стерта из памяти и. как уже можно догадаться, посмотреть или получить ее значение будет невозможно!

Так что же это такое — область видимости?

Диапазон инт

Область определяется “блоком” — вообще всякой областью, замкнутой в фигурные скобки, выход за которые сулит удаление данных объявленных в ней. Или как минимум — сокрытие их от других блоков, открытых вне текущего.

В Java область видимости определяется двумя основными способами:

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

Смотрим пример:

И как итог мы получим ошибку:

Error:(10, 21) java: cannot find symbol
symbol: variable y
location: class com.javaRush.test.type.Main

Области видимости могут быть вложенными (если мы объявили переменную в первом, внешнем блоке, то во внутреннем она будет видна).

Заключение

Сегодня мы познакомились с восемью примитивными типами в Java.

Эти типы можно разделить на четыре группы:

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

Как говорится, за всё нужно платить. Если мы хотим примитив с “крутым” (широким) диапазоном — что-то вроде long — мы жертвуем выделением большего куска памяти и в обратную сторону. Экономя память и используя byte, мы получаем ограниченный диапазон от -128 до 127.

Сокращенная запись создания и инициализации переменной

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

Выглядит эта команда так:

Краткая запись создания и инициализации переменной

Можно объявить и несколько переменных одной строкой. Тогда команда будет иметь вид:

= , = , =

Краткая запись создания и инициализации нескольких переменных

Диапазон инт

Диапазон инт

Диапазон инт

Целые типы

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

Самым часто используемым является тип int. Его название происходит от (целый). Все целочисленные литералы в коде имеют тип int (если в конце числа не указана буква L, F или D).

Переменные этого типа могут принимать значение от -2,147,483,648 до +2,147,483,647.

Это достаточно много и хватает почти для всех случаев жизни. Почти все функции, которые возвращают число, возвращают число типа int.

Тип short получил свое название от int. Его еще называют . В отличие от типа int, его длина всего два байта и возможный диапазон значений от -32,768 до +32,767.

То есть в нем даже число миллион не сохранишь. Даже 50 тысяч. Это самый редко используемый целочисленный тип в Java. В основном его используют, когда хотят сэкономить на памяти.

Допустим, у вас ситуация, когда заранее известно, что значения с которыми вы работаете не превышает 30 тысяч, и таких значений миллионы.

Например, вы пишете приложение, которое обрабатывает картинки сверхвысокой четкости: на один цвет приходится 10 бит. А точек у вас в картинке — миллион. И вот тут уже играет роль, используете вы тип int или short.

Этот тип получил свое название от int — его еще называют . В отличие от типа int, у него просто гигантский диапазон значений: от -9*1018 до
+9*1018

Почему же он не является основным целым типом?

Все дело в том, что Java появилась еще в середине 90-х, когда большинство компьютеров были 32-х разрядными. А это значило, что все процессоры были заточены под работу с числами из 32-х бит. С целыми числами из 64-х бит процессоры работать уже умели, но операции с ними были медленнее.

Поэтому программисты разумно решили сделать стандартным целым типом тип int, ну а тип long использовать только тогда, когда без него действительно не обойтись.

Это самый маленький целочисленный тип в Java, но далеко не самый редко используемый. Его название совпадает со словом byte — минимальная адресуемая ячейка памяти в Java.

Размер допустимых значений типа byte не так уж велик: от -128 до +127. Но не в этом его сила. Тип byte чаще всего используется, когда нужно хранить в памяти большой блок обезличенных данных. Массив типа byte просто идеально подходит для этих целей.

Например, вам нужно куда-то скопировать файл.

Вам не нужно обрабатывать содержимое файла: вы просто хотите создать область памяти (буфер), скопировать в нее содержимое файла, а затем записать эти данные из буфера в другой файл. Массив типа byte — то, что нужно для этих целей.

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

Присваивание значений

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

Присваивание значения переменной

Где значением может быть любое целочисленное выражение. Примеры:

Тип char

Среди примитивных типов в Java есть еще один, который заслуживает особого внимания — тип char. Его название происходит от слова , а сам тип используется для того, чтобы хранить символы.

А ведь символы — это как раз то, из чего состоят строки: каждая строка содержит в себе массив символов.

Но еще интереснее тот факт, что тип char — это и числовой тип тоже! Так сказать, тип двойного назначения.

Все дело в том, что на самом деле тип char хранит не символы, а из кодировки Unicode. Каждому символу соответствует число — числовой код символа.

Каждая переменная типа char занимает в памяти два байта (как и тип short). Но в отличие от типа short, целочисленный тип char — беззнаковый, и может хранить значения от 0 до 65,535.

Тип char — гибридный тип. Его значения можно интерпретировать и как числа (их можно складывать и умножать), и как символы. Так было сделано потому, что хоть символы и имеют визуальное представление, для компьютера они в первую очередь просто числа. И работать с ними как с числами гораздо удобнее.

— это специальная таблица (кодировка), которая содержит все символы мира. И у каждого символа есть свой номер. Выглядит она примерно так:

Диапазон инт

Присвоить значение переменной типа char можно разными способами.

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

И как мы говорили, тип char — это и целочисленный тип тоже, поэтому можно написать так:

Работа с типом char

Каждый символ char — это в первую очередь число (код символа), а потом уже символ. Зная код символа, всегда можно получить его в программе. Пример:

Вот самые известные коды символов:

Список примитивных типов

В Java есть 8 базовых примитивных типов. Примитивными их называют потому, что значения этих типов не являются объектами и хранятся прямо внутри переменных.

Вот таблица, которая содержит краткую информацию по этим типам:

Значение по умолчанию

Кстати, важный нюанс. Если вы объявили переменную-класса (поле класса) или статическую переменную-класса, и не присвоили ей никакого значения, она инициализируется значением по умолчанию. Список таких значений приведен в таблице.

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

Но давайте вернемся к примитивным типам и рассмотрим их подробнее

Про анемометры:  Газовые котлы без дымохода: особенности работы
Оцените статью
Анемометры