Арифметические типы
(См. также тип для обзора системы типов и список утилит, связанных с типами, предоставляемых библиотекой C.)
Тип Boolean
Обратите внимание, что преобразование в _Bool(до C23)bool(с C23) работает не так, как преобразование в другие целочисленные типы: | (с C99) |
Типы символов
-
signed char- тип для представления символов со знаком. -
unsigned char- тип для представления символов без знака. Также используется для проверки представлений объектов (сырой памяти). -
char- тип для представления символов. Эквивалентен либоsigned charилиunsigned char(который определяется реализацией и может контролироваться параметрами компилятора), ноcharявляется отдельным типом, отличным отsigned charиunsigned char.
Обратите внимание, что стандартная библиотека также определяет псевдонимы wchar_t , char16_t и char32_t(с C11) для представления широких символов и char8_t для символов UTF-8(с C23).
Целочисленные типы
-
short int(также доступен какshort, может использовать ключевое словоsigned) -
unsigned short int(также доступен какunsigned short) -
int(также доступен какsigned int) -
unsigned int(также доступен какunsigned), беззнаковый аналогint, реализующий арифметику по модулю. Подходит для манипуляций с битами. -
long int(также доступен какlong) -
unsigned long int(также доступен какunsigned long)
| (с C99) |
| (с C23) |
Примечание: как и со всеми спецификаторами типов, порядок не имеет значения: unsigned long long int и long int unsigned long обозначают один и тот же тип.
Следующая таблица суммирует все доступные целочисленные типы и их свойства:
| Спецификатор типа | Эквивалентный тип | Ширина в битах по модели данных | ||||
|---|---|---|---|---|---|---|
| Стандарт C | LP32 | ILP32 | LLP64 | LP64 | ||
char | char | не менее 8 | 8 | 8 | 8 | 8 |
signed char | signed char | |||||
unsigned char | unsigned char | |||||
short | short int | не менее 16 | 16 | 16 | 16 | 16 |
short int |
||||||
signed short |
||||||
signed short int |
||||||
unsigned short | unsigned short int | |||||
unsigned short int |
||||||
int | int | не менее 16 | 16 | 32 | 32 | 32 |
signed |
||||||
signed int |
||||||
unsigned | unsigned int | |||||
unsigned int |
||||||
long | long int | не менее 32 | 32 | 32 | 32 | 64 |
long int |
||||||
signed long |
||||||
signed long int |
||||||
unsigned long | unsigned long int | |||||
unsigned long int |
||||||
long long | long long int (C99) | не менее 64 | 64 | 64 | 64 | 64 |
long long int |
||||||
signed long long |
||||||
signed long long int |
||||||
unsigned long long | unsigned long long int (C99) |
|||||
unsigned long long int |
||||||
Помимо минимального количества бит, стандарт C гарантирует, что 1 == sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long).
Примечание: это позволяет крайний случай, в котором байт имеет размер 64 бита, все типы (включая char) имеют ширину 64 бита, и sizeof возвращает 1 для каждого типа.
Примечание: целочисленная арифметика определена по-разному для типов со знаком и без знака. См. арифметические операторы, в частности переполнение целых чисел.
Модели данных
Выбранные каждой реализацией размеры основных типов вместе образуют модель данных. Широкое распространение получили четыре модели данных:
Системы с 32-битными процессорами:
- LP32 или 2/4/4 (int 16-битный, long и указатель 32-битные)
- Win16 API
- ILP32 или 4/4/4 (int, long и указатель 32-битные);
- Win32 API
- Системы Unix и Unix-подобные (Linux, Mac OS X)
Системы с 64-битными процессорами:
- LLP64 или 4/4/8 (int и long 32-битные, указатель 64-битный)
- Win64 API
- LP64 или 4/8/8 (int 32-битный, long и указатель 64-битные)
- Системы Unix и Unix-подобные (Linux, Mac OS X)
Другие модели встречаются очень редко. Например, ILP64 (8/8/8: int, long и указатель 64-битные) встречался только в некоторых ранних 64-битных системах Unix (например, Unicos на Cray).
Обратите внимание, что типы целых чисел с точной шириной доступны в <stdint.h> начиная с C99.
Типы вещественных чисел с плавающей запятой
В C существует три или шесть(с C23) типа для представления вещественных значений с плавающей запятой:
-
float- тип с плавающей точкой одинарной точности. Соответствует формату IEEE-754 binary32, если поддерживается. -
double- тип с плавающей точкой двойной точности. Соответствует формату IEEE-754 binary64, если поддерживается. -
long double- тип с плавающей точкой расширенной точности. Соответствует формату IEEE-754 binary128, если поддерживается; в противном случае соответствует формату IEEE-754 binary64-extended, если поддерживается; в противном случае соответствует какому-либо формату расширенной плавающей точки, не соответствующему IEEE-754, при условии, что его точность выше, чем у binary64, а диапазон не хуже, чем у binary64; в противном случае соответствует формату IEEE-754 binary64.- Формат binary128 используется в некоторых реализациях HP-UX, SPARC, MIPS, ARM64 и z/OS.
- Наиболее известный формат IEEE-754 binary64-extended — это 80-битный формат расширенной точности x87. Он используется во многих реализациях x86 и x86-64 (заметным исключением является MSVC, который реализует
long doubleв том же формате, что иdouble, т.е. binary64).
| (с C23) |
Типы с плавающей точкой могут поддерживать особые значения:
- бесконечность (положительная и отрицательная), см.
INFINITY - отрицательный ноль,
-0.0. Он сравнивается как равный положительному нулю, но имеет значение в некоторых арифметических операциях, например,1.0/0.0 == INFINITY, но1.0/-0.0 == -INFINITY) - не число (NaN), которое не сравнивается как равное чему-либо (включая себя). Несколько битовых шаблонов представляют NaN, см.
nan,NAN. Обратите внимание, что C не обращает особого внимания на сигнализирующие NaN (определенные в IEEE-754) и рассматривает все NaN как тихие.
Действительные числа с плавающей точкой могут использоваться с арифметическими операторами + - / * и различными математическими функциями из <math.h>. Как встроенные операторы, так и функции библиотеки могут вызывать исключения с плавающей точкой и устанавливать errno, как описано в math_errhandling.
Выражения с плавающей точкой могут иметь больший диапазон и точность, чем указано в их типах, см. FLT_EVAL_METHOD. Присваивание, возврат и приведение типов изменяют диапазон и точность на ассоциированные с объявленным типом.
Выражения с плавающей точкой также могут быть сжатыми, то есть вычисляться так, как будто все промежуточные значения имеют бесконечный диапазон и точность, см. #pragma STDC FP_CONTRACT.
Некоторые операции с числами с плавающей точкой затрагиваются и изменяют состояние среды с плавающей точкой (в первую очередь, направление округления).
Неявные преобразования определены между типами с плавающей точкой, целыми, комплексными и мнимыми типами.
См. Пределы типов с плавающей точкой и <math.h> библиотеку для дополнительной информации, пределов и свойств типов с плавающей точкой.
Комплексные типы с плавающей точкойКомплексные типы с плавающей точкой моделируют математические комплексные числа, то есть числа, которые можно представить как сумму действительного числа и действительного числа, умноженного на мнимую единицу: a + bi Три комплексных типа:
Примечание: как и со всеми спецификаторами типов, любой порядок допустим: #include <complex.h>
#include <stdio.h>
int main(void)
{
double complex z = 1 + 2*I;
z = 1 / z;
printf("1/(1.0+2.0i) = %.1f%+.1fi\n", creal(z), cimag(z));
}Вывод: 1/(1.0+2.0i) = 0.2-0.4i
Каждый комплексный тип имеет такое же представление объекта и требования к выравниванию, как и массив из двух элементов соответствующего типа с плавающей точкой ( float a[4] = {1, 2, 3, 4};
float complex z1, z2;
memcpy(&z1, a, sizeof z1); // z1 becomes 1.0 + 2.0i
memcpy(&z2, a+2, sizeof z2); // z2 becomes 3.0 + 4.0iКомплексные числа могут использоваться с арифметическими операторами + - * и /, возможно, совместно с мнимыми и действительными числами. В Инкремент и декремент не определены для комплексных типов. Операторы сравнения не определены для комплексных типов (нет понятия «меньше»). Неявные преобразования определены между комплексными типами и другими арифметическими типами. Для поддержки модели с одной бесконечностью для комплексной арифметики C рассматривает любое комплексное значение с хотя бы одной бесконечной частью как бесконечность, даже если другая часть – NaN, гарантирует, что все операторы и функции соблюдают базовые свойства бесконечностей и предоставляет #include <complex.h>
#include <math.h>
#include <stdio.h>
int main(void)
{
double complex z = (1 + 0*I) * (INFINITY + I*INFINITY);
// textbook formula would give
// (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN
// but C gives a complex infinity
printf("%f%+f*i\n", creal(z), cimag(z));
// textbook formula would give
// cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN
// but C gives ±∞+i*nan
double complex y = cexp(INFINITY + I*NAN);
printf("%f%+f*i\n", creal(y), cimag(y));
}Возможный вывод: inf+inf*i inf+nan*i C также обрабатывает несколько бесконечностей таким образом, чтобы сохранить направленную информацию, где это возможно, несмотря на присущие ограничения декартового представления: умножение мнимой единицы на действительную бесконечность даёт корректно знаковое мнимое бесконечность: i × ∞ = i∞. Также, i × (∞ – i∞) = ∞ + i∞ указывает разумный квадрант. Мнимые типы с плавающей точкойМнимые типы с плавающей точкой моделируют математические мнимые числа, то есть числа, которые можно записать как действительное число, умноженное на мнимую единицу: bi. Три мнимых типа:
Примечание: как и со всеми спецификаторами типов, любой порядок допустим: #include <complex.h>
#include <stdio.h>
int main(void)
{
double imaginary z = 3*I;
z = 1 / z;
printf("1/(3.0i) = %+.1fi\n", cimag(z));
}Вывод: 1/(3.0i) = -0.3i
Каждый из трёх мнимых типов имеет такое же представление объекта и требование к выравниванию, как и соответствующий тип с плавающей точкой ( Примечание: несмотря на это, мнимые типы различны и не совместимы со своими соответствующими типами с плавающей точкой, что запрещает алиасинг. Мнимые числа могут использоваться с арифметическими операторами + - * и /, возможно, совместно с комплексными и действительными числами. В Инкремент и декремент не определены для мнимых типов. Неявные преобразования определены между мнимыми типами и другими арифметическими типами. Мнимые числа позволяют выразить все комплексные числа с помощью естественной нотации Мнимые типы также упрощают реализации; умножение мнимого на комплексное можно реализовать непосредственно двумя умножениями, если поддерживаются мнимые типы, вместо четырёх умножений и двух сложений. | (с C99) |
Ключевые слова
-
bool,true,false,char,int,short,long,signed,unsigned,float,double. -
_Bool,_BitInt,_Complex,_Imaginary,_Decimal32,_Decimal64,_Decimal128.
Диапазон значений
Следующая таблица предоставляет справку по пределам общих числовых представлений.
До C23 Стандарт C допускал любое представление целых чисел со знаком, а минимальный гарантированный диапазон целых чисел со знаком N-бит был от \(\scriptsize -(2^{N-1}-1)\)-(2N-1-1) до \(\scriptsize +2^{N-1}-1\)+2N-1-1 (например, -127 до 127 для целого 8-битного типа со знаком), что соответствует пределам дополнительного кода или метода со знаком и величиной.
Однако, все популярные модели данных (включая все ILP32, LP32, LP64, LLP64) и почти все компиляторы C используют представление в дополнительном коде (единственные известные исключения — некоторые компиляторы для UNISYS), и начиная с C23, это единственное разрешенное стандартом представление с гарантированным диапазоном от \(\scriptsize -2^{N-1}\)-2N-1 до \(\scriptsize +2^{N-1}-1\)+2N-1-1 (например, −128 до 127 для знакового 8-битного типа).
| Тип | Размер в битах | Формат | Диапазон значений | |
|---|---|---|---|---|
| Приблизительно | Точно | |||
| character | 8 | знаковый | −128 до 127 | |
| беззнаковый | 0 до 255 | |||
| 16 | UTF-16 | 0 до 65535 | ||
| 32 | UTF-32 | 0 до 1114111 (0x10ffff) | ||
| integer | 16 | знаковый | ± 3,27 · 104 | −32768 до 32767 |
| беззнаковый | 0 до 6,55 · 104 | 0 до 65535 | ||
| 32 | знаковый | ± 2,14 · 109 | −2 147 483 648 до 2 147 483 647 | |
| беззнаковый | 0 до 4,29 · 109 | 0 до 4 294 967 295 | ||
| 64 | знаковый | ± 9,22 · 1018 | −9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 | |
| беззнаковый | 0 до 1,84 · 1019 | 0 до 18 446 744 073 709 551 615 | ||
| двоично-плавающая точка | 32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
|
|
| 80[примечание 1] | x86 |
|
|
|
| 128 | IEEE-754 |
|
|
|
| десятичная плавающая точка | 32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
||
| 128 | IEEE-754 |
|
||
- Представление объекта обычно занимает 96/128 бит на 32/64-битных платформах соответственно.
Примечание: фактические (в отличие от гарантированных минимальных) диапазоны доступны в заголовках библиотеки <limits.h> и <float.h>.
См. также
| Документация C++ для Базовые типы |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/arithmetic_types