Arithmetic types
(Véase también type para una visión general del sistema de tipos y la lista de utilidades relacionadas con tipos que proporciona la biblioteca C.)
Tipo booleanoNótese que la conversión a _Bool (hasta C23) bool (desde C23) no funciona igual que la conversión a otros tipos enteros: ( bool ) 0.5 se evalúa como true , mientras que ( int ) 0.5 se evalúa como 0 . |
(desde C99) |
Tipos de caracteres
-
- signed char — tipo para representación de caracteres con signo.
- unsigned char — tipo para representación de caracteres sin signo. También se utiliza para inspeccionar representaciones de objetos (memoria en bruto).
- char — tipo para representación de caracteres. Equivalente a signed char o unsigned char (cuál de ellos depende de la implementación y puede ser controlado mediante un conmutador de línea de comandos del compilador), pero char es un tipo distinto, diferente tanto de signed char como de unsigned char .
Tenga en cuenta que la biblioteca estándar también define typedef names wchar_t , char16_t y char32_t (desde C11) para representar caracteres anchos y char8_t para caracteres UTF-8 (desde C23) .
Tipos enteros
-
- short int (también accesible como short , puede usar la palabra clave signed )
- unsigned short int (también accesible como unsigned short )
- int (también accesible como signed int )
- Este es el tipo entero más óptimo para la plataforma, y se garantiza que tiene al menos 16 bits. La mayoría de los sistemas actuales utilizan 32 bits (consulte Modelos de datos a continuación).
- unsigned int (también accesible como unsigned ), la contraparte sin signo de int , implementa aritmética modular. Adecuado para manipulaciones de bits.
- long int (también accesible como long )
- unsigned long int (también accesible como unsigned long )
|
(desde C99) |
|
(desde C23) |
Nota: como con todos los especificadores de tipo, cualquier orden está permitido: unsigned long long int y long int unsigned long nombran el mismo tipo.
La siguiente tabla resume todos los tipos enteros disponibles y sus propiedades:
| Especificador de tipo | Tipo equivalente | Ancho en bits por modelo de datos | ||||
|---|---|---|---|---|---|---|
| Estándar C | LP32 | ILP32 | LLP64 | LP64 | ||
|
char
|
char |
al menos
8 |
8 | 8 | 8 | 8 |
|
signed
char
|
signed char | |||||
|
unsigned
char
|
unsigned char | |||||
|
short
|
short int |
al menos
16 |
16 | 16 | 16 | 16 |
|
short
int
|
||||||
|
signed
short
|
||||||
|
signed
short
int
|
||||||
|
unsigned
short
|
unsigned short int | |||||
|
unsigned
short
int
|
||||||
|
int
|
int |
al menos
16 |
16 | 32 | 32 | 32 |
|
signed
|
||||||
|
signed
int
|
||||||
|
unsigned
|
unsigned int | |||||
|
unsigned
int
|
||||||
|
long
|
long int |
al menos
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) |
al menos
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
|
||||||
Además de los conteos mínimos de bits, el Estándar de C garantiza que
-
1
==
sizeof
(
char
)
≤sizeof ( short )≤sizeof ( int )≤sizeof ( long )≤sizeof ( long long ) .
Nota: esto permite el caso extremo en el cual los byte tienen un tamaño de 64 bits, todos los tipos (incluyendo char ) tienen 64 bits de ancho, y sizeof devuelve 1 para cada tipo.
Nota: la aritmética de enteros se define de manera diferente para los tipos de enteros con signo y sin signo. Consulte operadores aritméticos , en particular desbordamientos de enteros .
Modelos de datos
Las decisiones tomadas por cada implementación sobre los tamaños de los tipos fundamentales se conocen colectivamente como data model . Cuatro data models obtuvieron amplia aceptación:
Sistemas de 32 bits:
-
- LP32 o 2/4/4 ( int es de 16 bits, long y puntero son de 32 bits)
-
- API Win16
- ILP32 o 4/4/4 ( int , long , y puntero son de 32 bits);
-
- API Win32
- Sistemas Unix y similares a Unix (Linux, Mac OS X)
Sistemas de 64 bits:
-
- LLP64 o 4/4/8 ( int y long son de 32 bits, el puntero es de 64 bits)
-
- API Win64
- LP64 o 4/8/8 ( int es de 32 bits, long y el puntero son de 64 bits)
-
- Sistemas Unix y similares a Unix (Linux, Mac OS X)
Otros modelos son muy raros. Por ejemplo, ILP64 ( 8/8/8 : int , long , y los punteros son de 64 bits) solo apareció en algunos sistemas Unix tempranos de 64 bits (por ejemplo, Unicos en Cray ).
Tenga en cuenta que los tipos de enteros de ancho exacto están disponibles en <stdint.h> desde C99.
Tipos de coma flotante reales
C tiene tres o seis (desde C23) tipos para representar valores de punto flotante reales:
-
- float — tipo de coma flotante de precisión simple. Coincide con el formato IEEE-754 binary32 si está soportado.
- double — tipo de coma flotante de doble precisión. Coincide con el formato IEEE-754 binary64 si está soportado.
-
long
double
— tipo de coma flotante de precisión extendida. Coincide con el
formato IEEE-754
binary128
si está soportado, de lo contrario coincide con el
formato extendido IEEE-754
binary64
si está soportado, de lo contrario coincide con algún formato de coma flotante extendido no IEEE-754 siempre que su precisión sea mejor que
binary64
y su rango sea al menos tan bueno como
binary64
, de lo contrario coincide con el formato IEEE-754
binary64
.
- binary128 es utilizado por algunas implementaciones de HP-UX, SPARC, MIPS, ARM64 y z/OS.
- El formato extendido IEEE-754 binary64 más conocido es el formato de precisión extendida x87 de 80 bits. Es utilizado por muchas implementaciones x86 y x86-64 (una excepción notable es MSVC, que implementa long double en el mismo formato que double , es decir, binary64 ).
|
(desde C23) |
Los tipos de punto flotante pueden admitir valores especiales:
- infinito (positivo y negativo), consulte INFINITY
- el cero negativo , - 0.0 . Se compara igual al cero positivo, pero es significativo en algunas operaciones aritméticas, p.ej. 1.0 / 0.0 == INFINITY , pero 1.0 / - 0.0 == - INFINITY )
- no es un número (NaN), que no se compara igual con nada (incluyéndose a sí mismo). Múltiples patrones de bits representan NaNs, consulte nan , NAN . Nótese que C no presta atención especial a los NaNs señalizados (especificados por IEEE-754), y trata todos los NaNs como silenciosos.
Los números reales de punto flotante pueden utilizarse con
operadores aritméticos
+
-
/
*
y varias funciones matemáticas de
<math.h>
. Tanto los operadores incorporados como las funciones de biblioteca pueden generar excepciones de punto flotante y establecer
errno
como se describe en
math_errhandling
.
Las expresiones de punto flotante pueden tener mayor rango y precisión que el indicado por sus tipos, consulte FLT_EVAL_METHOD . Asignación , return , y cast fuerzan el rango y precisión al asociado con el tipo declarado.
Las expresiones de punto flotante también pueden ser contraídas , es decir, calculadas como si todos los valores intermedios tuvieran rango y precisión infinitos, consulte #pragma STDC FP_CONTRACT .
Algunas operaciones con números de punto flotante se ven afectadas por y modifican el estado de el entorno de punto flotante (especialmente, la dirección de redondeo).
Conversiones implícitas se definen entre tipos de coma flotante reales y tipos enteros, complejos e imaginarios.
Consulte Límites de tipos de punto flotante y la biblioteca <math.h> para detalles adicionales, límites y propiedades de los tipos de punto flotante.
Tipos complejos de punto flotanteLos tipos de punto flotante complejos modelan los números complejos matemáticos, es decir, los números que pueden escribirse como la suma de un número real y un número real multiplicado por la unidad imaginaria: a + bi Los tres tipos complejos son
Nota: como con todos los especificadores de tipo, cualquier orden está permitido: long double complex , complex long double , e incluso double complex long nombran el mismo tipo.
Ejecutar este código
Salida: 1/(1.0+2.0i) = 0.2-0.4i
Cada tipo complejo tiene la misma representación de objeto y requisitos de alineación que un arreglo de dos elementos del tipo real correspondiente ( float para float complex , double para double complex , long double para long double complex ). El primer elemento del arreglo contiene la parte real, y el segundo elemento del arreglo contiene el componente imaginario.
Los números complejos pueden utilizarse con
operadores aritméticos
Los operadores de incremento y decremento no están definidos para tipos complejos. Los operadores relacionales no están definidos para tipos complejos (no existe la noción de "menor que").
Para admitir el modelo de infinito único en la aritmética de números complejos, C considera cualquier valor complejo con al menos una parte infinita como un infinito incluso si su otra parte es un NaN, garantiza que todos los operadores y funciones respeten las propiedades básicas de los infinitos y proporciona cproj para mapear todos los infinitos al canónico (consulte operadores aritméticos para las reglas exactas).
Ejecutar este código
#include <complex.h> #include <math.h> #include <stdio.h> int main(void) { double complex z = (1 + 0*I) * (INFINITY + I*INFINITY); // la fórmula del libro de texto daría // (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN // pero C da un infinito complejo printf("%f%+f*i\n", creal(z), cimag(z)); // la fórmula del libro de texto daría // cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN // pero C da ±∞+i*nan double complex y = cexp(INFINITY + I*NAN); printf("%f%+f*i\n", creal(y), cimag(y)); } Salida posible: inf+inf*i inf+nan*i C también trata múltiples infinitos para preservar la información direccional cuando es posible, a pesar de las limitaciones inherentes de la representación cartesiana: multiplicar la unidad imaginaria por el infinito real da el infinito imaginario con el signo correcto: i × ∞ = i∞. Además, i × (∞ – i∞) = ∞ + i∞ indica el cuadrante razonable.
Tipos de coma flotante imaginariosLos tipos de punto flotante imaginarios modelan los números imaginarios matemáticos, es decir, números que pueden escribirse como un número real multiplicado por la unidad imaginaria: bi Los tres tipos imaginarios son
Nota: como con todos los especificadores de tipo, cualquier orden está permitido: long double imaginary , imaginary long double , e incluso double imaginary long nombran el mismo tipo.
Ejecutar este código
Salida: 1/(3.0i) = -0.3i
Cada uno de los tres tipos imaginarios tiene la misma representación de objeto y requisito de alineación que su tipo real correspondiente ( float para float imaginary , double para double imaginary , long double para long double imaginary ). Nota: a pesar de eso, los tipos imaginarios son distintos y no compatibles con sus tipos reales correspondientes, lo que prohíbe el aliasing.
Los números imaginarios pueden utilizarse con
operadores aritméticos
Los incrementos y decrementos no están definidos para tipos imaginarios.
Los números imaginarios permiten expresar todos los números complejos utilizando la notación natural x + I * y (donde I se define como _Imaginary_I ). Sin tipos imaginarios, ciertos valores complejos especiales no pueden crearse de forma natural. Por ejemplo, si I se define como _Complex_I , entonces escribir 0.0 + I * INFINITY produce NaN como parte real, y debe usarse CMPLX ( 0.0 , INFINITY ) en su lugar. Lo mismo ocurre con los números con componente imaginario de cero negativo, que son significativos al trabajar con funciones de biblioteca con cortes de rama, como csqrt : 1.0 - 0.0 * I resulta en el componente imaginario de cero positivo si I se define como _Complex_I y la parte imaginaria de cero negativo requiere el uso de CMPLX o conj . Los tipos imaginarios también simplifican las implementaciones; la multiplicación de un imaginario por un complejo puede implementarse directamente con dos multiplicaciones si se admiten los tipos imaginarios, en lugar de cuatro multiplicaciones y dos adiciones. |
(desde C99) |
Palabras clave
- bool , true , false , char , int , short , long , signed , unsigned , float , double .
- _Bool , _BitInt , _Complex , _Imaginary , _Decimal32 , _Decimal64 , _Decimal128 .
Rango de valores
La siguiente tabla proporciona una referencia para los límites de las representaciones numéricas comunes.
Antes de C23, el Estándar de C permitía cualquier representación de enteros con signo, y el rango mínimo garantizado de enteros con signo de N bits era desde
-(2
N-1
-1)
hasta
+2
N-1
-1
(por ejemplo,
-127
hasta
127
para un tipo con signo de 8 bits), lo que corresponde a los límites del
complemento a uno
o de la
representación signo-magnitud
.
Sin embargo, todos los modelos de datos populares (incluyendo todos los de ILP32, LP32, LP64, LLP64) y casi todos los compiladores de C utilizan
complemento a dos
(las únicas excepciones conocidas son algunos compiladores para UNISYS), y a partir de C23, es la única representación permitida por el estándar, con el rango garantizado desde
-2
N-1
hasta
+2
N-1
-1
(por ejemplo,
-128
hasta
127
para un tipo con signo de 8 bits).
| Tipo | Tamaño en bits | Formato | Rango de valores | |
|---|---|---|---|---|
| Aproximado | Exacto | |||
| carácter | 8 | con signo | −128 a 127 | |
| sin signo | 0 a 255 | |||
| 16 | UTF-16 | 0 a 65535 | ||
| 32 | UTF-32 | 0 a 1114111 ( 0x10ffff ) | ||
| entero | 16 | con signo | ± 3.27 · 10 4 | −32768 a 32767 |
| sin signo | 0 a 6.55 · 10 4 | 0 a 65535 | ||
| 32 | con signo | ± 2.14 · 10 9 | −2,147,483,648 a 2,147,483,647 | |
| sin signo | 0 a 4.29 · 10 9 | 0 a 4,294,967,295 | ||
| 64 | con signo | ± 9.22 · 10 18 | −9,223,372,036,854,775,808 a 9,223,372,036,854,775,807 | |
| sin signo | 0 a 1.84 · 10 19 | 0 a 18,446,744,073,709,551,615 | ||
|
punto flotante
binario |
32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
|
|
| 80 [nota 1] | x86 |
|
|
|
| 128 | IEEE-754 |
|
|
|
|
punto flotante
decimal |
32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
||
| 128 | IEEE-754 |
|
||
- ↑ La representación del objeto generalmente ocupa 96/128 bits en plataformas de 32/64 bits respectivamente.
Nota: los rangos reales (en oposición a los mínimos garantizados) están disponibles en los encabezados de la biblioteca <limits.h> y <float.h> .
Véase también
|
Documentación de C++
para
Tipos fundamentales
|