RAND_MAX
应至少为32767,但未说明此宏是否应展开为有符号或无符号整数。单一UNIX规范(link 1,link 2)和Linux man(link)没有提供任何明确的解释。
人们可能认为RAND_MAX
应该是一个有符号整数,因为这就是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 32767U
- DJGPP(DOS下的gcc 3.3.4):#define RAND_MAX 2147483647
- MinGW(Windows下的gcc 4.6.2):#define RAND_MAX 0x7FFF
- MS Visual Studio 2010(link):RAND_MAX被定义为值0x7fff
- Tiny C Compiler 0.9.25:#define RAND_MAX 0x7FFF
- lcc-win32 3.8:#define RAND_MAX 0x7fff
- Pelles C 6.50:#define RAND_MAX 0x3fffffff 或者 #define RAND_MAX 0x7fff
- Digital Mars C/C++ 8.52:#define RAND_MAX 32767
cos(w * t) + (rand() - RAND_MAX / 2) * 0.1 / (RAND_MAX / 2);
rand()
返回一个在[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
应该是有符号的,大多数编译器都这样定义,但是否有任何权威来源表明它应该是有符号的?旧标准?K&R?其他UNIX规范?
RAND_MAX
是<integer constant expression ≥ 32767>
。 K&R的《C编程语言》(第2版1988年)仅在与int rand()
函数相关时提到它,称后者返回范围在0
到RAND_MAX
之间的值。听起来对我来说是有符号的。 - martineauinteger
并不仅指int
,unsigned
和int
一样是integer
。 - Alexey Frunzeint
等同于signed
或signed int
,因此将相同的规则与语言规范中“整数”一词的所有用法相关联是合理的。除此之外,RAND_MAX
唯一的目的是用于描述int rand()
函数返回值的限制,这进一步加强了这种假设。也就是说,为什么要将某个东西定义为只用于指定库函数返回值可能的范围,而该库函数返回的是一个signed
类型的数量呢? - martineauRAND_MAX
必须是有符号(甚至是无符号)或明确允许为有符号或无符号的地方,而不是一个合理的假设(这一部分我们没有问题)。目前的措辞隐含地允许两者。这可能是出于历史(兼容性)原因,以免使现有的无符号实现失效。 - Alexey Frunze