Kernighan, B. W. and Ritchie, D. M. "The 'C' Programming Language"; Chapter 15
15. Преобразования.
Ряд операций может в зависимости от своих операндов вызыватьпреобразование значения операнда из одного типа в другой. В этомразделе об'ясняются результаты, которые следует ожидать от такихпреобразований. В п. 15.6 подводятся итоги преобразований, требуемыебольшинством обычных операций; эти сведения дополняются необходимымобразом при обсуждении каждой операции.
Содержание
- 15.1. Символы и целые.
- 15.2. Типы float и double - плавающей и двойной точности.
- 15.3. Плавающие и целочисленные величины.
- 15.4. Указатели и целые
- 15.5. Целое без знака.
- 15.6. Арифметические преобразования.
- 15.2. Типы float и double - плавающей и двойной точности.
15.1. Символы и целые.
Символ или короткое целое можно использовать всюду, где можноиспользовать целое. Во всех случаях значение преобразуется к целому.Преобразование более короткого целого к более длинному всегдасопровождается знаковым расширением; целые являются величинами сознаком. Осуществляется или нет знаковое расширение для символов,зависит от используемой машины, но гарантируется, что членстандартного набора символов неотрицателен. Из всех машин,рассматриваемых в этом руководстве, только pdp-11 осуществляет знаковоерасширение. Область значений символьных переменных на pdp-11 меняетсяот -128 до 127; символы из набора ascii имеют положительные значения.Символьная константа, заданная с помощью восьмеричной условнойпоследовательности, подвергается знаковому расширению и можетоказаться отрицательной; например, '\377' имеет значение -1.
Когда более длинное целое преобразуется в более короткое или в char,оно обрезается слева; лишние биты просто отбрасываются.
15.2. Типы float и double - плавающей и двойной точности.
Вся плавающая арифметика в "C" выполняется с двойной точностьюкаждый раз, когда об'ект типа float появляется в выражении, онудлиняется до double посредством добавления нулей в его дробнуючасть. Когда об'ект типа double должен быть преобразован к типуfloat, например, при присваивании, перед усечением double округляетсядо длины float.
15.3. Плавающие и целочисленные величины.
Преобразование плавающих значений к целочисленному типу имееттенденцию быть до некоторой степени машинно-зависимым; в частностинаправление усечения отрицательных чисел меняется от машине к машине.Результат не определен, если значение не помещается в предоставляемоепространство.
Преобразование целочисленных значений в плавающие выполняется безосложнений. Может произойти некоторая потеря точности, если длярезультата не содержится достаточного количества битов.
15.4. Указатели и целые
Целое или длинное целое может быть прибавлено к указателю или вычтеноиз него; в этом случае первая величина преобразуется так, какуказывается в разделе описания операции сложения.
Два указателя на об'екты одинакового типа могут быть вычтены; в этомслучае результат преобразуется к целому, как указывается в разделеописания операции вычитания.
15.5. Целое без знака.
Всякий раз, когда целое без знака об'единяется с простым целым,простое целое преобразуется в целое без знака и результат оказываетсяцелым без знака. Значением является наименьшее целое без знака,соответствующее целому со знаком (по модулю 2**размер слова). Вдвоичном дополнительном представлении это преобразование являетсячисто умозрительным и не изменяет фактическую комбинацию битов.
Когда целое без знака преобразуется к типу long, значение результатасовпадает со значением целого без знака. Таким образом, этопреобразование сводится к добавлению нулей слева.
15.6. Арифметические преобразования.
Подавляющее большинство операций вызывает преобразование и определяеттипы результата аналогичным образом. Приводимая ниже схема вдальнейшем будет называться "обычными арифметическимипреобразованиями".
- Сначала любые операнды типа char или shortпреобразуются в int, а любые операнды типаfloat преобразуются в double.
- Затем, если какой-либо операнд имеет типdouble, то другой преобразуется к типу double,и это будет типом результата.
- В противном случае, если какой-либо операндимеет тип long, то другой операнд преобразуетсяк типу long, и это и будет типом результата.
- В противном случае, если какой-либо операндимеет тип unsigned, то другой операндпреобразуется к типу unsigned, и это будет типомрезультата.
- В противном случае оба операнда будут иметьтип int, и это будет типом результата.