Преобразования типов которые компилятор делает автоматически java. Преобразование строк Java в значения других типов. Пример. Продвижение из типа byte в тип int, в котором выражение содержит операнд-переменную типа int

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

ТИП Метод для преобразова- Метод для преобразования из строки

ния В строку

boolean String.valueOf(boolean) new.Boolean(String). booleanvalue()

byte String.valueOf(byte) Byte.parseByte(string, int)

short String.valueOf(short) Short.parseShort(string, int)

int String.valueOf(int) Integer.parseInteger(string, int)

long String.valueOf(long) Long.parseLong(String, int)

float String.valueOf(float) Float.parseFloat(String)

double String.valueOf(double) Double.parseDouble(String)

Для преобразования строки в значение Boolean необходимо создать объект Boolean и затем запросить его значение. Все остальные классы-оболочки содержат Соответствующие методы parse. Методы parse целочисленных типов существуют в двух перегруженных формах: первая, помимо строки, требует задания дополнительного аргумента типа int, представляющего основание системы счисления – от 2 до 32; вторая принимает только параметр строки и по умолчанию предполагает использование десятичной системы счисления. Во всех случаях, кроме Boolean, предполагается следующее: если строка представляет значение, которое не может быть корректно преобразовано в число соответствующего типа, выбрасывается исключение NumberFormatException. Класс Boolean удовлетворяет соглашению, в соответствии с которым любая строка-параметр, не равная “true” (без учета регистра символов), приводит к созданию объекта вооlеаn со значением false.

Методов, позволяющих преобразовать символы, которые представлены в одной из поддерживаемых языком форм (таких как \b, \uxxxx и т.д.), В значения типа char и наоборот, не существует. Чтобы получить объект String, содержащий единственный символ, достаточно вызвать метод String.valueOf, передав ему в качестве параметра соответствующее значение типа char.

Отсутствуют также и способы создания строковых представлений чисел, заданных в одном из поддерживаемых языком форматов – с ведущим нулем (О), обозначающим восьмеричное число, и префиксом Ох (или ОХ), служащим признаком шестнадцатеричной системы счисления. Напротив, в целочисленных классах-оболочках поддерживаются версии метода decode, способного преобразовать строки в числовые значения соответствующего типа и “понимающего”, что ведущий О обозначает восьмеричное число, а один из префиксов Ох ИЛИ Ох – шестнадцатеричное.

Любой прикладной класс способен обеспечить поддержку преобразований собственных объектов в строки и обратно, если в его объявлении будет соответствующим образом переопределен метод toString и предусмотрен специальный конструктор, создающий объект класса на основе строки, переданной в качестве параметра. В вашем распоряжении имеется также метод String.valueOf(Object obj), который возвращает либо строковый объект “null” (если значение obj равно null), либо результат работы метода obj.toString. Класс String содержит достаточное количество перегруженных версий метода valueOf, позволяющих преобразовать любое значение любого типа в объект String посредством простого вызова valueOf с передачей нужного аргумента.

Иногда возникают ситуации, когда у вас есть величина какого-то определенного типа, а вам нужно ее присвоить переменной другого типа. Для некоторых типов это можно проделать и без приведения типа, в таких случаях говорят об автоматическом преобразовании типов. В Java автоматическое преобразование возможно только в том случае, когда точности представления чисел переменной-приемника достаточно для хранения исходного значения. Такое преобразование происходит, например, при занесении литеральной константы или значения переменной типа byte или short в переменную типа int. Это называется расширением (widening ) или повышением (promotion ), поскольку тип меньшей разрядности расширяется (повышается) до большего совместимого типа. Размера типа int всегда достаточно для хранения чисел из диапазона, допустимого для типа byte, поэтому в подобных ситуациях оператора явного приведения типа не требуется. Обратное в большинстве случаев неверно, поэтому для занесения значения типа int в переменную типа byte необходимо использовать оператор приведения типа. Эту процедуру иногда называют сужением (narrowing ), поскольку вы явно сообщаете транслятору, что величину необходимо преобразовать, чтобы она уместилась в переменную нужного вам типа. Для приведения величины к определенному типу перед ней нужно указать этот тип, заключенный в круглые скобки. В приведенном ниже фрагменте кода демонстрируется приведение типа источника (переменной типа int) к типу приемника (переменной типа byte). Если бы при такой операции целое значение выходило за границы допустимого для типа byte диапазона, оно было бы уменьшено путем деления по модулю на допустимый для byte диапазон (результат деления по модулю на число - это остаток от деления на это число),

int а = 100;
byte b = (byte) а;

2.2.1. Автоматическое преобразование типов в выражениях

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

byte а = 40;
byte b = 50;
byte с = 100;
int d = a* b / с ;

Результат промежуточного выражения (а*b) вполне может выйти за диапазон допустимых для типа byte значений. Именно поэтому Java автоматически повышает тип каждой части выражения до типа int, так что для промежуточного результата (а* b) хватает места.

Автоматическое преобразование типа иногда может оказаться причиной неожиданных сообщений транслятора об ошибках. Например, показанный ниже код, хотя и выглядит вполне корректным, приводит к сообщению об ошибке на фазе трансляции. В нем мы пытаемся записать значение 50*2, которое должно прекрасно уместиться в тип byte, в байтовую переменную. Но из-за автоматического преобразования типа результата в int мы получаем сообщение об ошибке от транслятора - ведь при занесении int в byte может произойти потеря точности.

byte b = 50;
b = b* 2:
^ Incompatible type for =. Explicit cast needed to convert int to byte.
(Несовместимый тип для =. Необходимо явное преобразование int в byte)

Исправленный текст:
byte b = 50;
b = (byte) (b* 2);

что приводит к занесению в b правильного значения 100.

Если в выражении используются переменные типов byte, short и int, то во избежание переполнения тип всего выражения автоматически повышается до int. Если же в выражении тип хотя бы одной переменной - long, то и тип всего выражения тоже повышается до long. Не забывайте, что все целые литералы, в конце которых не стоит символ L (или 1), имеют тип int.

Если выражение содержит операнды типа float, то и тип всего выражения автоматически повышается до float. Если же хотя бы один из операндов имеет тип double, то тип всего выражения повышается до double. По умолчанию Java рассматривает все литералы с плавающей точкой как имеющие тип double. Приведенная ниже про1рамма показывает, как повышается тип каждой величины в выражении для достижения соответствия со вторым операндом каждого бинарного оператора.

class Promote {
public static void main (String args ) {
byte b= 42;
char с = "a’;
shorts = 1024;
int i = 50000;
float f = 5.67f;
doubled =.1234;
double result = (f*b) + (i/ c) - (d* s);
System, out. println ((f* b)+ "+ "+ (i / c)+ " -" + (d* s));
System, out. println ("result = "+ result); }
}

Подвыражение f*b - это число типа float, умноженное на число типа byte, поэтому его тип автоматически повышается до float. Тип следующего подвыражения i / с (int, деленный на char) повышается до int. Аналогично этому тип подвыражения d*s (double, умноженный на short) повышается до double. На следующем шаге вычислений мы имеем дело с тремя промежуточными результатами типов float, int и double. Сначала при сложении первых двух тип int повышается до float и получается результат типа float. При вычитании из него значения типа double тип результата повышается до double. Окончательный результат всего выражения - значение типа double.

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

class SimpleTypes {
public static void main(String args ) {
byte b = 0x55;
short s = 0x55ff;
int i = 1000000;
long l = 0xffffffffL;
char с = ’a’;
float f= .25f;
double d = .00001234;
boolean bool = true;
System.out.println("byte b = " + b);
System.out.println("short s = " +s);
System.out.println("int i =” + i);
System.out.println("long 1 = " + l);
System.out.println("char с =” + с );
System.out.println("float f = " + f);
System.out.println("double d = " + d);
System.out.println("boolean bool =” + bool); }
}

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

byte b = 85
shorts = 22015
int i = 1000000
long 1 = 4294967295
char с = a
float f = 0.25
double d=1.234e-005
boolean bool = true

Обратите внимание на то, что целые числа печатаются в десятичном представлении, хотя мы задавали значения некоторых из них в шестнадцатиричном формате.

Данная статья:

  • написана командой . Надеемся, что она Вам будет полезна. Приятного прочтения!
  • это одна из статей из нашего

Преобразование типов - это тема, которая может показаться сложной начинающим программировать на Java. Однако, заверим Вас, на самом деле всё просто. Главное понять по каким законам происходит взаимодействие между переменными и помнить об этом при написании программ . Итак, давайте разбираться.

В Java существует 2 типа преобразований - картинка Вам в помощь:

Напомним, что вся "Вселенная Java" состоит из:

  • примитивных типов (byte, short, int, long, char, float, double, boolean)
  • объектов

В данной статье мы:

  • рассмотрим преобразование типов для примитивных типов переменных
  • преобразование объектов (String, Scanner и др.) в этой статье не рассматривается, поскольку с объектами происходит отдельная «магия» - это тема для отдельной статьи.
Автоматическое преобразование

Ну, что ж, давайте попробуем разобраться что такое "автоматическое преобразование".

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

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

Давайте, сравним, например:

1. byte и short. byte имеет меньший диапазон допустимых значений, чем short. То есть byte это как бы коробочка поменьше, а short - это коробочка побольше. И значит, мы можем byte вложить в short.

2. byte и int . byte имеет меньший диапазон допустимых значений, чем int. То есть byte это как бы коробочка поменьше, а int - это коробочка побольше. И значит, мы можем byte вложить в int.

3. int и long. int имеет меньший диапазон допустимых значений, чем long. То есть int это как бы коробочка поменьше, а long - это коробочка побольше. И значит, мы можем int вложить в long.

Это и есть пример автоматического преобразования. Это можно схематически изобразить в виде вот такой картинки:

Давайте рассмотрим как это работает на практике.

Пример №1

Код №1 - если Вы запустите это код на своем компьютере,

class Test { public static void main(String args) { byte a = 15; byte b = a; System.out.println(b); } }

class Test {

byte a = 15 ;

byte b = a ;

Код №2 - если Вы запустите это код на своем компьютере, в консоли будет выведено число 15

class Test { public static void main(String args) { byte a = 15; int b = a; System.out.println(b); } }

class Test {

public static void main (String args ) {

byte a = 15 ;

int b = a ;

System . out . println (b ) ;

И-и-и? Вы думаете, что раз в консоль было выведено одно и то же число, и код №1 отличается от кода №2 всего лишь типом переменной b, то между ними нет никакой разницы? Э то не так.

В коде №2 присутствует автоматическое преобразование типов , а в коде №1 - нет:

Хотя число, в принципе, одно и то же, но теперь оно находится в бо льшем контейнере, который занимает больше места на диске. При этом, JVM выполняет автоматические преобразования за Вас. Она знает, что int больше чем byte .

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

Другое дело если вы пытаетесь переложить что-то из большего контейнера в более маленький.

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

Поэтому, вы должны «прямо сказать», что ситуация под контролем:

class Test { public static void main(String args) { int a=0; long b=15; a = (int) b; } }

class Test {

public static void main (String args ) {

int a = 0 ;

long b = 15 ;

a = (int ) b ;

Тут мы дописали (int) перед b . Если бы переменная a была, к примеру, типа byte , в скобках бы стояло (byte) . Общая формула выглядит так:

Она говорит "сделай из (большего) значения b переменную нужного мне (целевого) типа int ".

Если что-то пошло не так.

До этого мы рассматривали ситуации, предполагая, что мы точно знаем, что делаем. Но что если попытаться поместить в контейнер то, что туда не помещается?

Оказывается, в контейнере останется лишь то, что туда «влезло». К примеру, у чисел с плавающей точкой будет «отсекаться» дробная часть:

//пример 1 class Test { public static void main(String args) { double a=11.2345; int b=(int)a; System.out.println(b); // в консоли получится число 11 } }

//пример 1

class Test {

public static void main (String args ) {

double a = 11.2345 ;

int b = (int ) a ;

System . out . println (b ) ; // в консоли получится число 11

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

А что будет, если мы попытаемся поместить число, которое выходит за допустимые границы? Например, если в byte (диапазон byte от -128 до 127) положить число 128? Думаете, мы получим 1? Нет. Мы получим -128:

class Test { public static void main(String args) { double a=128; byte b=(byte)a; System.out.println(b); //в консоли увидим -128 } }

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

Задания:
  1. Последовательно пропишите в компиляторе преобразования всех примитивных типов друг к другу, включая типы char и Составьте таблицу такого вида:
byte short char int long float double boolean
byte
short
char
int
Long
Float
double
boolean

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

* приведение типа к самому себе называется тождественным – его прописывать не обязательно

  1. Посмотрите еще раз, какой размер имеет каждый примитивный тип. Попытайтесь составить блок-схему, показывающую, куда помещаются какие типы. Проведите стрелочки с надписью «расширяющее преобразование» и «сужающее преобразование».
Вопросы

На собеседовании на должность Junior Java Developer Вас могут спросить:

Что Вы знаете о преобразовании примитивных типов данных, есть ли потеря данных, можно ли преобразовать логический тип?

Попробуйте ответить на вопрос.

Подытожим:
  • Если Вы "кладёте" в больший контейнер содержимое меньшего контейнера», преобразование происходит автоматически, и ошибок возникать не должно.
  • Если есть необходимость положить «значение из большего контейнера в меньший», нужно быть осторожным, и пользоваться явным приведением типов.
  • При приведении float или double к целочисленным типам, дробная часть не округляется, а просто отбрасывается.
  • Тип boolean не приводится ни к одному из типов.
  • Тип char приводится к числовым типам, как код символа в системе UNICODE.
  • Если число больше своего контейнера, результат будет непредсказуемым.

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

Надеемся, что наша статья была Вам полезна. Также есть возможность записаться на наши курсы по Java в Киеве. Обучаем с нуля. Детальную информацию Вы можете найти у нас на .


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

Пример 1. Присвоение значения переменной одного типа другому

int i = 11; byte b = 22; i = b;

В Java существует 2 типа преобразований - автоматическое преобразование (неявное) и приведение типов (явное преобразование) .

1. Автоматическое преобразование

Рассмотрим сначала автоматическое преобразование. Если оба типа совместимы, их преобразование будет выполнено в Java автоматически. Например, значение типа byte всегда можно присвоить переменной типа int , как это показано в примере 1.

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

  • оба типа должны быть совместимы
  • длина целевого типа должна быть больше длины исходного типа

В этом случае происходит преобразование с расширением .

Следующая схема показывает расширяющее преобразование в Java:

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

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

Стоит немного пояснить почему, к примеру тип byte не преобразуется автоматически (не явно) в тип char , хотя тип byte имеет ширину 8 бит, а char - 16, тоже самое касается и преобразования типа short в char . Это происходит потому, что byte и short знаковые типы данных, а char без знаковый. Поэтому в данном случае требуется использовать явное приведение типов, поскольку компилятору надо явно указать что вы знаете чего хотите и как будет обрабатываться знаковый бит типов byte и short при преобразовании к типу char .

Поведение величины типа char в большинстве случаев совпадает с поведением величины целого типа, следовательно, значение типа char можно использовать везде, где требуются значения int или long . Однако напомним, что тип char не имеет знака, поэтому он ведет себя отлично от типа short , несмотря на то что диапазон обоих типов равен 16 бит.

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

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

Чтобы выполнить преобразование двух несовместимых типов данных, нужно воспользоваться приведением типов. Приведение - это всего лишь явное преобразование типов. Общая форма приведения типов имеет следующий вид:

(целевой_тип) значение

где параметр целевой_тип обозначает тип, в который нужно преобразовать указанное значение.

Пример 2. Приведение типов

Например, в следующем фрагменте кода тип int приводится к типу byte :

Int i = 11; byte b = 22; b = (byte) i;

Пример 3. Преобразования значений с плавающей точкой в целые числа

Рассмотрим пример преобразования значений с плавающей точкой в целые числа. В этом примере дробная часть значения с плавающей точкой просто отбрасывается (операция усечения):

Double d = 3.89; int a = (int) d; //Результат будет 3

Пример 4. Преобразования более емкого целого типа к менее емкому целому числу

При приведении более емкого целого типа к менее емкому старшие биты просто отбрасываются:

Int i = 323; byte b = (byte) i; //Результат будет 67

Пример 5. Преобразования более емкого значения с плавающей точкой к менее емкому целому числу

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

Double d = 389889877779.89; short s = (short) d; //Результат будет -1

3. Автоматическое продвижение типов в выражениях

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

В языке Java действуют следующие правила:

  1. Если один операнд имеет тип double double .
  2. float , другой тоже преобразуется к типу float .
  3. Иначе, если один операнд имеет тип long , другой тоже преобразуется к типу long .
  4. Иначе оба операнда преобразуются к типу int .
  5. В выражениях совмещенного присваивания (+=,-=,*=,/=) нет необходимости делать приведение.

Приведем пример:

Пример 6. Автоматическое продвижение типов в выражениях

При умножении переменной b1 (byte ) на 2 (int ) результат будет типа int . Поэтому при попытке присвоить результат в переменную b2 (byte ) возникнет ошибка компиляции. Но при использовании совмещенной операции присваивания (*=), такой проблемы не возникнет.

Byte b1 = 1; byte b2 = 2 * b1; //Ошибка компиляции int i1 = 2 * b1; b2 *= 2;

Пример 7. Автоматическое продвижение типов в выражениях

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

Public class IntegerDemo1 { public static void main(String args) { byte b1 = 50, b2 = -99; short k = b1 + b2; //ошибка компиляции System.out.println("k=" + k); } }

Пример 8. Автоматическое продвижение типов в выражениях

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

Public class IntegerDemo2 { public static void main(String args) { byte b1 = 50, b2 = -99; b1 += b2; System.out.println("b1=" + b1); } }

Аннотация: Эта лекция посвящена вопросам преобразования типов. Поскольку Java – язык строго типизированный, компилятор и виртуальная машина всегда следят за работой с типами, гарантируя надежность выполнения программы. Однако во многих случаях то или иное преобразование необходимо осуществить для реализации логики программы. С другой стороны, некоторые безопасные переходы между типами Java позволяет осуществлять неявным для разработчика образом, что может привести к неверному пониманию работы программы. В лекции рассматриваются все виды преобразований, а затем все ситуации в программе, где они могут применяться. В заключение приводится начало классификации типов переменных и типов значений, которые они могут хранить. Этот вопрос будет подробнее рассматриваться в следующих лекциях.

Что все это означает? Начнем по порядку. Для простых типов расширение означает, что осуществляется переход от менее емкого типа к более емкому. Например, от типа byte (длина 1 байт) к типу int (длина 4 байта). Такие преобразования безопасны в том смысле, что новый тип всегда гарантированно вмещает в себя все данные, которые хранились в старом типе, и таким образом не происходит потери данных. Именно поэтому компилятор осуществляет его сам, незаметно для разработчика:

byte b=3; int a=b;

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

Следующие 19 преобразований являются расширяющими:

  • от byte к short , int , long , float , double
  • от short к int , long , float , double
  • от char к int , long , float , double
  • от int к long , float , double
  • от long к float , double
  • от float к double

Обратите внимание, что нельзя провести преобразование к типу char от типов меньшей или равной длины (byte , short ), или, наоборот, к short от char без потери данных. Это связано с тем, что char , в отличие от остальных целочисленных типов, является беззнаковым.

Тем не менее, следует помнить, что даже при расширении данные все-таки могут быть в особых случаях искажены. Они уже рассматривались в предыдущей лекции, это приведение значений int к типу float и приведение значений типа long к типу float или double . Хотя эти дробные типы вмещают гораздо большие числа, чем соответствующие целые, но у них меньше значащих разрядов.

Повторим этот пример:

long a=111111111111L; float f = a; a = (long) f; print(a);

Результатом будет:

Обратное преобразование - сужение - означает, что переход осуществляется от более емкого типа к менее емкому. При таком преобразовании есть риск потерять данные. Например, если число типа int было больше 127, то при приведении его к byte значения битов старше восьмого будут потеряны. В Java такое преобразование должно совершаться явным образом, т.е. программист в коде должен явно указать, что он намеревается осуществить такое преобразование и готов потерять данные.

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

  • от byte к char
  • от short к byte , char
  • от char к byte , short
  • от int к byte , short , char
  • от long к byte , short , char , int
  • от float к byte , short , char , int , long
  • от double к byte , short , char , int , long , float

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

print((byte)383); print((byte)384); print((byte)-384);

Результатом будет:

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

Это верно и для типа char :

char c=40000; print((short)c);

Результатом будет:

Сужение дробного типа до целочисленного является более сложной процедурой. Она проводится в два этапа.

На первом шаге дробное значение преобразуется в long , если целевым типом является long , или в int - в противном случае (целевой тип byte , short , char или int ). Для этого исходное дробное число сначала математически округляется в сторону нуля, то есть дробная часть просто отбрасывается.

Например, число 3,84 будет округлено до 3 , а -3,84 превратится в -3 . При этом могут возникнуть особые случаи:

  • если исходное дробное значение является NaN , то результатом первого шага будет 0 выбранного типа (т.е. int или long );
  • если исходное дробное значение является положительной или отрицательной бесконечностью, то результатом первого шага будет, соответственно, максимально или минимально возможное значение для выбранного типа (т.е. для int или long );
  • наконец, если дробное значение было конечной величиной, но в результате округления получилось слишком большое по модулю число для выбранного типа (т.е. для int или long ), то, как и в предыдущем пункте, результатом первого шага будет, соответственно, максимально или минимально возможное значение этого типа. Если же результат округления укладывается в диапазон значений выбранного типа, то он и будет результатом первого шага.
  • и int вполне очевидны - дробные бесконечности преобразовались в, соответственно, минимально и максимально возможные значения этих типов. Результат для следующих трех типов (short , char , byte ) есть, по сути, дальнейшее сужение значений, полученных для int , согласно второму шагу процедуры преобразования. А делается это, как было описано, просто за счет отбрасывания старших битов. Вспомним, что минимально возможное значение в битовом виде представляется как 1000..000 (всего 32 бита для int , то есть единица и 31 ноль). Максимально возможное - 1111..111 (31 единица). Отбрасывая старшие биты, получаем для отрицательной бесконечности результат 0 , одинаковый для всех трех типов. Для положительной же бесконечности получаем результат, все биты которого равняются 1

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



Есть вопросы?

Сообщить об опечатке

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