sirve - tipos de datos primitivos en c



valor mínimo y máximo del tipo de datos en C (6)

¿Cuál es la función para determinar el mínimo y máximo posible del valor de los tipos de datos (es decir, int, char.etc) en C?

https://src-bin.com


Answer #1

"Pero glifo", te escucho preguntar, "¿y si tengo que determinar el valor máximo para un tipo opaco cuyo máximo podría cambiar?" Puede continuar: "¿Qué pasa si es un typedef en una biblioteca que no controlo?"

Me alegra que me hayas preguntado, porque acabo de pasar un par de horas cocinando una solución (que luego tuve que tirar, porque no resolvió mi problema real).

Puede utilizar esta útil macro maxof para determinar el tamaño de cualquier tipo de entero válido.

#define issigned(t) (((t)(-1)) < ((t) 0))

#define umaxof(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | \
                    (0xFULL << ((sizeof(t) * 8ULL) - 4ULL)))

#define smaxof(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | \
                    (0x7ULL << ((sizeof(t) * 8ULL) - 4ULL)))

#define maxof(t) ((unsigned long long) (issigned(t) ? smaxof(t) : umaxof(t)))

Puedes usarlo así:

int main(int argc, char** argv) {
    printf("schar: %llx uchar: %llx\n", maxof(char), maxof(unsigned char));
    printf("sshort: %llx ushort: %llx\n", maxof(short), maxof(unsigned short));
    printf("sint: %llx uint: %llx\n", maxof(int), maxof(unsigned int));
    printf("slong: %llx ulong: %llx\n", maxof(long), maxof(unsigned long));
    printf("slong long: %llx ulong long: %llx\n",
           maxof(long long), maxof(unsigned long long));
    return 0;
}

Si lo desea, puede lanzar un '(t)' al frente de esas macros para que le den el resultado del tipo sobre el que está preguntando, y no tiene que hacer un casting para evitar advertencias.


Answer #2

El archivo de cabecera limits.h define macros que se expanden a varios límites y parámetros de los tipos de entero estándar.


Answer #3

Los valores MIN y MAX de cualquier tipo de datos enteros se pueden calcular sin utilizar ninguna función de biblioteca como la siguiente y la misma lógica se puede aplicar a otros tipos enteros cortos, int y largos.

printf("Signed Char : MIN -> %d & Max -> %d\n", ~(char)((unsigned char)~0>>1), (char)((unsigned char)~0 >> 1));
printf("Unsigned Char : MIN -> %u & Max -> %u\n", (unsigned char)0, (unsigned char)(~0));

Answer #4

Mire estas páginas en limits.h y float.h , que se incluyen como parte de la biblioteca c estándar.


Answer #5

Valor máximo de cualquier tipo integral sin signo : (~(t)0)

Valor máximo de cualquier tipo integral con signo : si tiene una variante sin signo de tipo t, ((t)((~(unsigned t)0)>>1)) le dará el resultado más rápido que necesita (vea el ejemplo en el kernel de Linux) el código fuente al que se hace referencia a continuación). De lo contrario, probablemente deberías usar (~(1ULL<<(sizeof(t)*CHAR_BIT-1))) .

Valor mínimo de cualquier tipo integral firmado : debe conocer la representación numérica firmada de su máquina. La mayoría de las máquinas usan complemento de 2, por lo que -(~(1ULL<<(sizeof(t)*CHAR_BIT-1)))-1 funcionará para usted.

Para detectar si su máquina usa el complemento 2, detecte si (~(t)0U) y (t)(-1) representan lo mismo. Entonces, combinado con lo anterior:

((~(t)0U) == (t)(-1) ? -(~(1ULL<<(sizeof(t)*CHAR_BIT-1)))-1 :
                       -(~(1ULL<<(sizeof(t)*CHAR_BIT-1))))

le dará el valor mínimo de cualquier tipo integral firmado. (De hecho, hay otras representaciones de esto si conoce la representación del complemento de 2. Por ejemplo, (t)(1ULL<<(sizeof(t)*CHAR_BIT-1)) debería ser equivalente a (t)(-(~(1ULL<<(sizeof(t)*CHAR_BIT-1)))-1) )

Por ejemplo: (~ (size_t) 0) le da el valor máximo de size_t. (Y adivina qué, así es como SIZE_MAX está # definido en el código fuente del kernel de Linux ).

Sin embargo, una advertencia : todas estas expresiones utilizan el tipo de conversión y, por lo tanto, no funcionan en los condicionales del preprocesador (#if ... #elif ... #endif y similares).


Answer #6

Deberá usar limits.h que proporcione las siguientes constantes (según la referencia enlazada):

CHAR_BIT   = number of bits in a char
SCHAR_MIN  = minimum value for a signed char
SCHAR_MAX  = maximum value for a signed char
UCHAR_MAX  = maximum value for an unsigned char
CHAR_MIN   = minimum value for a char
CHAR_MAX   = maximum value for a char
MB_LEN_MAX = maximum multibyte length of a character accross locales
SHRT_MIN   = minimum value for a short
SHRT_MAX   = maximum value for a short
USHRT_MAX  = maximum value for an unsigned short
INT_MIN    = minimum value for an int
INT_MAX    = maximum value for an int
UINT_MAX   = maximum value for an unsigned int
LONG_MIN   = minimum value for a long
LONG_MAX   = maximum value for a long
ULONG_MAX  = maximum value for an unsigned long
LLONG_MIN  = minimum value for a long long
LLONG_MAX  = maximum value for a long long
ULLONG_MAX = maximum value for an unsigned long long

Donde U*_MIN se omite por razones obvias (cualquier tipo sin signo tiene un valor mínimo de 0).

Del limits.h modo, limits.h proporciona límites para los tipos float y double :

-FLT_MAX = most negative value of a float
FLT_MAX  = max value of a float
-DBL_MAX = most negative value of a double
DBL_MAX  = max value of a double
-LDBL_MAX = most negative value of a long double
LDBL_MAX = max value of a long double

Debes leer el artículo en floats.h cuidadosamente, aunque float y double pueden contener los valores mínimos y máximos prescritos, pero la precisión con la que cada tipo puede representar datos puede no coincidir con lo que estás intentando almacenar. En particular, es difícil almacenar números excepcionalmente grandes con fracciones extremadamente pequeñas adjuntas. Entonces float.h proporciona varias otras constantes que lo ayudan a determinar si un float o un double pueden, de hecho, representar un número en particular.





types