RAND_MAX宏:符号或无符号? [英] RAND_MAX macro: signed or unsigned?
问题描述
我看过了C标准(1999年),它只是说 RAND_MAX
至少应为32767,但没有谈到这个宏是否应该扩展为说签署或一个unsigned int。统一UNIX规范(链接1 ,的链接2 )和Linux的人(的链接)不添加任何清晰。
I've looked up the C standard (from 1999) and it only says that RAND_MAX
should be at least 32767 but says nothing about whether this macro should expand to a signed or an unsigned int. The Single UNIX Specification (link 1, link 2) and Linux man (link) don't add any clarity.
有人会认为 RAND_MAX
应该是符号int
因为那是兰特()
的回报。
One would think RAND_MAX
should be a signed int
since that's what rand()
returns.
不过,我发现,有些编译器把它定义为无符号:
However, I've found that some compilers define it as unsigned:
- 古代的Turbo C ++ 1.01:#定义RAND_MAX 0x7FFFU
- 不那么古老的C ++ Builder的5.5:#定义RAND_MAX 0x7FFFU
- 的还活着公开赛在Watcom C / C ++ 1.9:#定义RAND_MAX 32767U
- DJGPP(DOS版的gcc 3.3.4):#定义RAND_MAX 2147483647
- MinGW的(用于Windows 4.6.2 GCC):#定义RAND_MAX 0x7FFF的
- MS Visual Studio 2010中(链接):< I> RAND_MAX被定义为数值0x7FFF的的
- 微小的C编译器0.9.25:#定义RAND_MAX 0x7FFF的
- LCC-win32的3.8:#定义RAND_MAX 0x7FFF的
- PellesÇ6.50:#定义RAND_MAX 0x3fffffff 或的#define RAND_MAX 0x7FFF的
- 数字火星的C / C ++ 8.52:#定义RAND_MAX 32767
- The ancient Turbo C++ 1.01: #define RAND_MAX 0x7FFFU
- The not so ancient C++ Builder 5.5: #define RAND_MAX 0x7FFFU
- The still alive Open Watcom C/C++ 1.9: #define RAND_MAX 32767U
- DJGPP (gcc 3.3.4 for DOS): #define RAND_MAX 2147483647
- MinGW (gcc 4.6.2 for Windows): #define RAND_MAX 0x7FFF
- MS Visual Studio 2010 (link): RAND_MAX is defined as the value 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 OR #define RAND_MAX 0x7fff
- Digital Mars C/C++ 8.52: #define RAND_MAX 32767
这使得看似无害code像下面变成非便携和炸毁由于签署无符号的推广:
This makes seemingly innocuous code like the below become non-portable and blow up due to signed to unsigned promotion:
cos(w * t) + (rand() - RAND_MAX / 2) * 0.1 / (RAND_MAX / 2);
兰特()
返回值的范围在[0, RAND_MAX <α
符号int
/ code>。
rand()
returns a signed int
in the range [0,RAND_MAX
].
如果 RAND_MAX
定义为 unsigned int类型
,从兰特()的值
提升为 unsigned int类型
了。
If RAND_MAX
is defined as an unsigned int
, the value from rand()
gets promoted to unsigned int
too.
如果是这样的话,差异(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]
And if that's the case, the difference (rand() - RAND_MAX / 2)
becomes an unsigned difference of unsigned integers with the value in the ranges [0,RAND_MAX
-RAND_MAX
/2] & [UINT_MAX
+1-RAND_MAX
/2,UINT_MAX
-1] instead of being a signed difference of signed integers with the value in the range [-RAND_MAX
/2,RAND_MAX
-RAND_MAX
/2].
总之,它看起来像 RAND_MAX
应签署并最多(?)编译器将其定义为这样的,但有没有,说应该签署任何权威的来源?旧标准? K&安培; R?另一个UNIX规范?
Anyhow, it seems like RAND_MAX
should be signed and most(?) compilers define it as such, but is there any authoritative source that says it should be signed? Older standard? K&R? Another UNIX spec?
推荐答案
答案是:code正在无理的假设,因此它需要修复。这是什么code应该做的是投 RAND_MAX
到(INT)
使用情况。
The answer is: that code is making an unwarranted assumption, so it needs to be fixed. What that code should have done is cast RAND_MAX
to (int)
on usage.
虽然它将使更多的意义编译器为签订定义其 RAND_MAX
宏,标准非常谨慎,要求他们这样做。这使得它一个可移植的bug任何code盲目认为它签署。
While it would make a bit more sense for compilers to define their RAND_MAX
macros as signed, the standard carefully avoids requiring them to do so. That makes it a portability bug for any code to blindly assume it to be signed.
这篇关于RAND_MAX宏:符号或无符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!