RAND_MAX macro: ¿firmado o sin firmar?
He buscado el estándar C (desde 1999) y solo dice queRAND_MAX
debería ser al menos 32767 pero no dice nada sobre si esta macro debería expandirse a un int firmado o sin firmar. La única especificación de UNIX (enlace 1, enlace 2) y Linux man (enlazar) No agregue ninguna claridad.
Uno pensaríaRAND_MAX
debería ser unsigned int
ya que eso es lo querand()
devoluciones.
Sin embargo, he encontrado que algunos compiladores lo definen como sin firmar:
El antiguo Turbo C ++ 1.01: # define RAND_MAX0x7FFFUEl no tan antiguo C ++ Builder 5.5: # define RAND_MAX0x7FFFUEl aún abierto Open Watcom C / C ++ 1.9: #define RAND_MAX32767UDJGPP (gcc 3.3.4 para DOS): # define RAND_MAX 2147483647MinGW (gcc 4.6.2 para Windows): # define RAND_MAX 0x7FFFMS Visual Studio 2010 (enlazar):RAND_MAX se define como el valor 0x7fffCompilador Tiny C 0.9.25: # define RAND_MAX 0x7FFFlcc-win32 3.8: # define RAND_MAX 0x7fffPelles C 6.50: #define RAND_MAX 0x3fffffffO #define RAND_MAX 0x7fffDigital Mars C / C ++ 8.52: # define RAND_MAX 32767Esto hace que el código aparentemente inocuo como el que se muestra a continuación se vuelva no portátil y explote debido a la promoción firmada a no firmada:
cos(w * t) + (rand() - RAND_MAX / 2) * 0.1 / (RAND_MAX / 2);
rand()
devuelve unsigned int
en el rango [0,RAND_MAX
].
SiRAND_MAX
se define como unaunsigned int
, el valor derand()
obtiene ascendido aunsigned 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 [0,RAND_MAX
-RAND_MAX
/ 2] & [UINT_MAX
+ 1-RAND_MAX
/ 2,UINT_MAX
-1] en lugar de ser una diferencia con signo de enteros con signo con el valor en el rango [-RAND_MAX
/ 2,RAND_MAX
-RAND_MAX
/ 2].
De todos modos, parece queRAND_MAX
deben estar firmados y la mayoría de (?) los compiladores lo definen como tal, pero ¿hay alguna fuente autorizada que diga que debería estar firmada? ¿Estándar más antiguo? K&R? Otra especificación de UNIX?