其中一些仅吐出0,而其他一些吐出正确的随机数。我认为这与将它们强制转换为无符号整数并丢弃小数部分有关,但是强制转换到底在哪里进行?
#include <cstdlib>
#include <ctime>
#include <iostream>
const unsigned NUM_MIN {0};
const unsigned NUM_MAX {50};
int main ()
{
// Seed random number generator.
std::srand(static_cast<unsigned>(time(nullptr)));
size_t times {};
do
{
// Get a random number between NUM_MIN and NUM_MAX.
unsigned number {NUM_MIN + std::rand() / ((RAND_MAX + 1u) / NUM_MAX)}; // Works
// unsigned number {NUM_MIN + std::rand() / (RAND_MAX / NUM_MAX)}; // Works.
// unsigned number {NUM_MIN + (std::rand() / RAND_MAX) / NUM_MAX}; // Does not work.
// unsigned number {NUM_MIN + std::rand() / RAND_MAX / NUM_MAX}; // Does not work.
// unsigned number {NUM_MIN + (std::rand() / RAND_MAX) * NUM_MAX}; // Also does not work.
// unsigned number {NUM_MIN + (std::rand() / (RAND_MAX + 1u)) * NUM_MAX}; // Doesn't work.
std::cout << number << std::endl;
} while (++times < 20);
return EXIT_SUCCESS;
}
答案 0 :(得分:2)
并不是在所有情况下都是“问题”。
还有一个事实是整数除法会产生积分结果。对于正操作数,四舍五入总是朝着零。
不同操作数具有不同优先级的事实。乘法和除法比加法和减法具有更高的优先级(并且所有算法都具有从左到右的关联性)。方括号()
用于覆盖。
unsigned number {NUM_MIN + std::rand() / ((RAND_MAX + 1u) / NUM_MAX)};
将RAND_MAX
转换为unsigned
(因为已将其添加到1u
中)。然后,由于两个操作数均为unsigned
,因此((RAND_MAX + 1u) / NUM_MAX)
产生类型为unsigned
的结果。 std::rand()
的结果将转换为unsigned
。表达式中的所有其他运算都有unsigned
个操作数,并产生unsigned
个结果。
unsigned number {NUM_MIN + std::rand() / (RAND_MAX / NUM_MAX)};
RAND_MAX
被转换为unsigned
,所以(RAND_MAX / NUM_MAX)
产生类型为unsigned
的结果。然后将std::rand()
转换为unsigned
进行除法,此表达式中的所有其他操作都具有unsigned
个操作数和unsigned
个结果。
unsigned number {NUM_MIN + (std::rand() / RAND_MAX) / NUM_MAX}; unsigned number {NUM_MIN + std::rand() / RAND_MAX / NUM_MAX}; unsigned number {NUM_MIN + (std::rand() / RAND_MAX) * NUM_MAX};
在所有这三种情况下,std::rand()
和RAND_MAX
都给出类型为int
的正值,因此std::rand() / RAND_MAX
被计算为int
。这将为零,因为RAND_MAX
是rand()
返回的结果的上限。将该零值转换为unsigned
以除以NUM_MAX
(在第三种情况下是乘法),并且所有其他运算都用unsigned
操作数和结果执行。最终结果是number
将被初始化为等于NUM_MIN
。
unsigned number {NUM_MIN + (std::rand() / (RAND_MAX + 1u)) * NUM_MAX};
这里的逻辑与前面的逻辑相同,除了使用unsigned
完成除法之外。
您可能还想重新定义“作品”的定义。您评论为“作品”的两个示例会产生不同的结果。