Namespaces
Variants

Arithmetic types

From cppreference.net

(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.)

Contenidos

Tipo booleano

  • _Bool (también accesible como la macro bool ) (hasta C23) bool (desde C23) — tipo, capaz de contener uno de los dos valores: 1 y 0 (también accesibles como las macros true y false ) (hasta C23) true y false (desde C23) .

Nó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 )
  • long long int (también accesible como long long )
  • unsigned long long int (también accesible como unsigned long long )
(desde C99)
  • _BitInt ( n ) (también accesible como signed _BitInt ( n ) ), los tipos de enteros con signo de precisión de bits (donde n es reemplazado por una expresión constante entera que denota el ancho preciso (incluyendo el bit de signo), que no puede ser mayor que BITINT_MAXWIDTH de <limits.h> )
  • unsigned _BitInt ( n ) , los tipos de enteros sin signo de precisión de bits (donde n es reemplazado por una expresión constante entera que denota el ancho preciso, que no puede ser mayor que BITINT_MAXWIDTH de <limits.h> )
(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 ).
Si la implementación predefine la macro constante __STDC_IEC_60559_DFP__ , los siguientes tipos de punto flotante decimal también están soportados.
De lo contrario, estos tipos de punto flotante decimal no están soportados.
(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 flotante

Los 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.

#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));
}

Salida:

1/(1.0+2.0i) = 0.2-0.4i

Si la macro constante __STDC_NO_COMPLEX__ está definida por la implementación, los tipos complejos (así como el encabezado de biblioteca <complex.h> ) no están disponibles.

(desde C11)

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.

float a[4] = {1, 2, 3, 4};
float complex z1, z2;
memcpy(&z1, a, sizeof z1); // z1 se convierte en 1.0 + 2.0i
memcpy(&z2, a+2, sizeof z2); // z2 se convierte en 3.0 + 4.0i

Los números complejos pueden utilizarse con operadores aritméticos + - * y / , posiblemente mezclados con números imaginarios y reales. Existen muchas funciones matemáticas definidas para números complejos en <complex.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 .

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").

Conversiones implícitas are defined between complex types and other arithmetic types.

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).

#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 imaginarios

Los 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.

#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));
}

Salida:

1/(3.0i) = -0.3i

Se recomienda, pero no se requiere, que una implementación que define __STDC_IEC_559_COMPLEX__ admita números imaginarios. POSIX recomienda verificar si la macro _Imaginary_I está definida para identificar el soporte de números imaginarios.

(hasta C11)

Los números imaginarios son compatibles si __STDC_IEC_559_COMPLEX__ (hasta C23) __STDC_IEC_60559_COMPLEX__ (desde C23) está definido.

(desde C11)

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 + - * y / , posiblemente mezclados con números complejos y reales. Existen muchas funciones matemáticas definidas para números imaginarios en <complex.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 .

Los incrementos y decrementos no están definidos para tipos imaginarios.

Conversiones implícitas are defined between imaginary types and other arithmetic types.

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

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
  • subnormal mínimo:
    ± 1.401,298,4 · 10 −45
  • normal mínimo:
    ± 1.175,494,3 · 10 −38
  • máximo:
    ± 3.402,823,4 · 10 38
  • subnormal mínimo:
    ±0x1p−149
  • normal mínimo:
    ±0x1p−126
  • máximo:
    ±0x1.fffffep+127
64 IEEE-754
  • subnormal mínimo:
    ± 4.940,656,458,412 · 10 −324
  • normal mínimo:
    ± 2.225,073,858,507,201,4 · 10 −308
  • máximo:
    ± 1.797,693,134,862,315,7 · 10 308
  • subnormal mínimo:
    ±0x1p−1074
  • normal mínimo:
    ±0x1p−1022
  • máximo:
    ±0x1.fffffffffffffp+1023
80 [nota 1] x86
  • subnormal mínimo:
    ± 3.645,199,531,882,474,602,528
    · 10 −4951
  • normal mínimo:
    ± 3.362,103,143,112,093,506,263
    · 10 −4932
  • máximo:
    ± 1.189,731,495,357,231,765,021
    · 10 4932
  • subnormal mínimo:
    ±0x1p−16445
  • normal mínimo:
    ±0x1p−16382
  • máximo:
    ±0x1.fffffffffffffffep+16383
128 IEEE-754
  • subnormal mínimo:
    ± 6.475,175,119,438,025,110,924,
    438,958,227,646,552,5 · 10 −4966
  • normal mínimo:
    ± 3.362,103,143,112,093,506,262,
    677,817,321,752,602,6 · 10 −4932
  • máximo:
    ± 1.189,731,495,357,231,765,085,
    759,326,628,007,016,2 · 10 4932
  • subnormal mínimo:
    ±0x1p−16494
  • normal mínimo:
    ±0x1p−16382
  • máximo:
    ±0x1.ffffffffffffffffffffffffffff
    p+16383
punto flotante
decimal
32 IEEE-754
  • subnormal mínimo:
    ± 1 · 10 -101
  • normal mínimo:
    ± 1 · 10 -95
  • máximo:
    ± 9.999'999 · 10 96
64 IEEE-754
  • subnormal mínimo:
    ± 1 · 10 -398
  • normal mínimo:
    ± 1 · 10 -383
  • máximo:
    ± 9.999'999'999'999'999 · 10 384
128 IEEE-754
  • subnormal mínimo:
    ± 1 · 10 -6176
  • normal mínimo:
    ± 1 · 10 -6143
  • máximo:
    ± 9.999'999'999'999'999'999'
    999'999'999'999'999 · 10 6144
  1. 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