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

Что происходит, когда int умножается на float, какой тип данных будет результатом? Как насчет double, разделенного на int? Есть ли способ предсказать, какой тип данных будет присвоен результату? Ответ — да, C++ следует набору правил при выполнении математических операций над переменными разных типов данных. Как и офицеры в армии, типы данных также ранжируются. Один тип данных превосходит другой, если он может содержать большее число. Например, double опережает float, а float опережает int. В таблице ниже перечислены типы данных в порядке их ранга, от высшего к низшему.

Единственным исключением из ранжирования в таблице является случай, когда int и long имеют одинаковый размер. В этом случае unsigned int имеет преимущество перед long, поскольку может содержать более высокое значение. Когда значение преобразуется в более высокий тип данных, оно называется повышенным. Понизить значение означает преобразовать его в более низкий тип данных. Давайте рассмотрим некоторые конкретные правила, которые диктуют вычисление математических выражений.

Правило 1. chars, shorts и unsigned shorts автоматически преобразуются в int. .

Вы заметите, что char, short и unsigned short не отображаются в таблице. Это потому, что каждый раз, когда они используются в математическом выражении, они преобразуются в int. Единственным исключением из этого правила является случай, когда unsigned short содержит значение больше, чем может содержать int. Это может произойти в системах, где short имеет тот же размер, что и int. В этом случае unsigned short преобразуется в unsigned int.

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

В следующем выражении предположим, что length — это int, а width — это число с плавающей запятой:

length * width

Прежде чем произойдет умножение, length будет преобразовано в число с плавающей запятой.

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

В следующем операторе предположим, что area — это двойное число, а length и widthfloat. с:

area = length * width

Поскольку length и width являются float, а площадь — double, результат умножения будет преобразован в двойник, потому что область была инициализирована как двойник.

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

int x, y = 4; 
float z = 2.7; 
x = y * z;

В выражении y * z y будет преобразовано в с плавающей запятой, а 10,8 будет результатом умножения. Однако, поскольку x является целым числом, 10,8 будет усечено, а 10 будет сохранено в x.

Когда вы делите целое число на другое целое число в C++, результатом всегда является целое число. Если есть остаток, он будет сброшен. Например, в следующем коде parts присваивается значение 2,0:

double parts;
parts = 15 / 6;

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

double parts; 
parts = 15.0 / 6;

В этом коде значение 15.0 интерпретируется как число с плавающей запятой, поэтому операция деления вернет число с плавающей запятой. Значение 2,5 будет присвоено parts.