Macro RAND_MAX: assinada ou não assinada?
Eu olhei para o padrão C (de 1999) e só diz queRAND_MAX
deve ser pelo menos 32767, mas não diz nada sobre se essa macro deve se expandir para um int assinado ou não assinado. A especificação única do UNIX (link 1, link 2) e Linux man (ligação) não adicione clareza.
Alguém poderia pensarRAND_MAX
devia ser umsigned int
desde que é issorand()
retorna.
No entanto, descobri que alguns compiladores definem como não assinados:
O antigo Turbo C ++ 1.01: #define RAND_MAX0x7FFFUO não tão antigo C ++ Builder 5.5: #define RAND_MAX0x7FFFUO ainda vivo 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 (ligação):RAND_MAX é definido como o valor 0x7fffCompilador C minúsculo 0.9.25: #define RAND_MAX 0x7FFFlcc-win32 3.8: #define RAND_MAX 0x7fffPelles C 6.50: #define RAND_MAX 0x3fffffffOU #define RAND_MAX 0x7fffDigital Mars C / C ++ 8.52: #define RAND_MAX 32767Isso torna o código aparentemente inócuo, como o seguinte, tornar-se não portátil e explodir devido à assinatura da promoção não assinada:
cos(w * t) + (rand() - RAND_MAX / 2) * 0.1 / (RAND_MAX / 2);
rand()
retorna umsigned int
no intervalo [0,RAND_MAX
].
E seRAND_MAX
é definido como umunsigned int
, o valor derand()
é promovido aunsigned int
também.
E se esse for o caso, a diferença(rand() - RAND_MAX / 2)
torna-se uma diferença sem sinal de inteiros sem sinal com o valor nos intervalos [0,RAND_MAX
-RAND_MAX
/ 2] e [UINT_MAX
+ 1-RAND_MAX
/ 2UINT_MAX
-1] em vez de ser uma diferença assinada de inteiros assinados com o valor no intervalo [-RAND_MAX
/ 2RAND_MAX
-RAND_MAX
/ 2].
De qualquer forma, parece queRAND_MAX
deve ser assinado e a maioria dos compiladores (?) o define como tal, mas existe alguma fonte autoritativa que diz que ele deve ser assinado? Padrão mais antigo? K & R? Outra especificação do UNIX?