Макрос RAND_MAX: подписанный или неподписанный?
Я посмотрел стандарт C (с 1999 года), и это говорит только о том, чтоRAND_MAX
начение @ должно быть не менее 32767, но ничего не говорит о том, должен ли этот макрос расширяться до целого числа со знаком или без знака. Единая спецификация UNIX link 1, link 2) и Linux man ссылк) не добавляй ясности.
Один бы подумалRAND_MAX
должен бытьsigned int
так как это то, чтоrand()
возвращается.
Однако я обнаружил, что некоторые компиляторы определяют его как неподписанный:
Древний Turbo C ++ 1.01: #define RAND_MAX 0x7FFFU Не очень древний C ++ Builder 5.5: #define RAND_MAX 0x7FFFU Еще жива Open Watcom C / C ++ 1.9: #define RAND_MAX 32767UDJGPP (gcc 3.3.4 для DOS): #define RAND_MAX 2147483647MinGW (gcc 4.6.2 для Windows): #define RAND_MAX 0x7FFFMS Visual Studio 2010 ссылк):RAND_MAX определяется как значение 0x7fffTiny C Compiler 0.9.25: #define RAND_MAX 0x7FFF lcc-win32 3.8: #define RAND_MAX 0x7fffPelles C 6.50: #define RAND_MAX 0x3fffffffИЛ #define RAND_MAX 0x7fffDigital Mars C / C ++ 8.52: #define RAND_MAX 32767Это делает на первый взгляд безобидный код, подобный приведенному ниже, непереносимым и взрывается из-за подписанной рекламы без подписи:
cos(w * t) + (rand() - RAND_MAX / 2) * 0.1 / (RAND_MAX / 2);
rand()
возвращаетsigned int
в диапазоне [0,RAND_MAX
].
ЕслиRAND_MAX
определяется какunsigned int
, значение отrand()
получает повышение доunsigned int
слишком
А если это так, то разница(rand() - RAND_MAX / 2)
становится беззнаковой разностью целых чисел без знака со значением в диапазонах [0,RAND_MAX
-RAND_MAX
/ 2] & UINT_MAX
+ 1-RAND_MAX
/ 2,UINT_MAX
-1] вместо разницы в знаковых целых числах со значением в диапазоне [-RAND_MAX
/ 2,RAND_MAX
-RAND_MAX
/ 2].
Похоже,RAND_MAX
должен быть подписан, и большинство (?) компиляторов определяют его как таковой, но есть ли авторитетный источник, который говорит, что он должен быть подписан? Старый стандарт? К & R? Еще одна спецификация UNIX?