He buscado el estándar C (desde 1999) y solo dice que RAND_MAX
debe ser al menos 32767 pero no dice nada sobre si esta macro debe expandirse a una int firmada o no firmada. Las especificaciones únicas de UNIX (link 1, link 2) y Linux man (link) no agregan ninguna claridad.macro RAND_MAX: ¿firmado o sin firmar?
Uno pensaría que RAND_MAX
debería ser un , ya que eso es lo que rand()
devuelve.
Sin embargo, he encontrado que algunos compiladores lo definen como sin signo:
- La antigua Turbo C++ 1.01: #define RAND_MAX 0x7FFFU
- El no tan antigua C++ Builder 5.5: #define RAND_MAX 0x7FFFU
- El sigue vivo abierto Watcom C/C++ 1.9: #define RAND_MAX 32767U
- DJGPP (gcc 3.3.4 para DOS): #define RAND_MAX 2147483647
- MinGW (4.6.2 gcc para Windows): #define RAND_MAX 0x7FFF
- MS Visual Studio 2010 (link): RAND_MAX se define como el valor 0x7FFF
- compilador C Tiny 0.9.25: # definir RAND_MAX 0x7FFF
- lcc-win32 3,8: #define RAND_MAX 0x7FFF
- Pelles C 6,50: #define RAND_MAX 0x3FFFFFFF O #define RAND_MAX 0x7FFF
- digital Marte C/C++ 8.52: #define RAND_MAX 32767
Esto hace que el código aparentemente inocuo como el no portátil a continuación convertido y volar debido al firmado con la promoción sin firmar:
cos(w * t) + (rand() - RAND_MAX/2) * 0.1/(RAND_MAX/2);
rand()
devuelve un signed int
en el rango [0, RAND_MAX
].
Si RAND_MAX
se define como un unsigned int
, el valor de rand()
es ascendido a unsigned int
también.
Y si ese es el caso, la diferencia (rand() - RAND_MAX/2)
se convierte en una diferencia sin signo de enteros sin signo con el valor en los rangos de [0, RAND_MAX
- RAND_MAX
/2] & [UINT_MAX
+ 1- RAND_MAX
/2, UINT_MAX
-1] en lugar de ser una diferencia firmada de enteros con signo con el valor en el rango [- RAND_MAX
/2, RAND_MAX
- RAND_MAX
/2].
De todos modos, parece que RAND_MAX
debe estar firmado y la mayoría de los compiladores (?) Lo definen como tal, pero ¿hay alguna fuente autorizada que diga que debe estar firmado? Mayor estándar? K & R? ¿Otra especificación de UNIX?
El libro _Standard C_ por Plaguer y Brodie (1989) en el estándar ANSI/ISO dice 'RAND_MAX' es' '. El lenguaje de programación de K & R _ (2nd-Ed 1988) solo lo menciona en relación con la función 'int rand()' que dice que este último devuelve un valor en el rango '0' a' RAND_MAX'. Sonidos firmados para mí. –
martineau
@martineau Me suena inesperado. 'entero 'no significa' int' exclusivamente, 'unsigned' es como' integer' como 'int'. –
Un 'int' no calificado es equivalente a un' signed' o 'signed int', por lo que sería razonable asociar las mismas reglas a todos los usos de la palabra" integer "en la especificación del lenguaje. Además de eso, el hecho es que el único propósito de 'RAND_MAX' era tener algo con lo que describir los límites de los valores devueltos por la función' int rand() 'solo refuerza aún más esa suposición. es decir, ¿por qué '# define' algo para ser una cantidad' unsigned' que solo se usaría para especificar el rango de posibles valores de retorno de una función de biblioteca que devolvió una cantidad 'signed '? – martineau