logo
Методичка Java

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

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

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

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

Рассмотрим теперь правила совместимости типов по присваиванию. Они просты: диапазон значений типа левой части не должен быть уже, чем диапазон типа правой. Поэтому в присваиваниях, где тип в правой части не умещается в диапазон левой части, требуется указывать явное преобразование типа. Иначе компилятор выдаст сообщение об ошибке с не очень адекватной диагностикой “possible loss of precision” (“возможная потеря точности”).

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

double d=1.5;

Величину d можно преобразовать к типу float таким образом:

(float)d

Аналогично, если имеется величина f типа float, её можно преобразовать в величину типа double таким образом:

(double)f

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

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

double d=1.5;

float f=(float)d;

Другие примеры допустимых присваиваний:

byte byte0=1; //-128..127

short short0=1;//- 32768.. 32767

char char0=1;//0.. 65535

int int0=1; //- 2.147483648E9.. 2.147483647E9

long long0=1;//-9.223E18.. 9.223E18

float float0=1;// ±(1.4E-45..3.402E38)

double double0=1;// ±(4.9E-324..1.797E308 )

short0=byte0;

byte0=(byte)short0;

char0=(char)short0;

int0=short0;

int0=char0;

char0=(char)int0;

short0=(short)int0;

long0=byte0;

byte0=(byte)long0;

long0=char0;

long0=int0;

int0=(int)long0;

float0=byte0;

float0=int0;

float0=(float)double0;

double0=float0;