我有一个包含7个元素的数组,我试图在0到6之间得到一个随机数,这样我就可以随机选择数组中的一个元素。
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class Color{
public:
Color(){
colors[0] = "red";
colors[1] = "orange";
colors[2] = "yellow";
colors[3] = "green";
colors[4] = "blue";
colors[5] = "indigo";
colors[6] = "violet";
}
void printColors()
{
for (int i = 0; i<sizeof(colors)/sizeof(colors[0]); ++i)
{
cout << colors[i] << endl;
}
}
void printRandomColor()
{
int random_integer = rand() % 7;
cout << random_integer << endl;
}
private:
string colors[7];
};
int main(int argc, const char * argv[]) {
srand( static_cast<unsigned int>(time(0)));
Color colorObject;
colorObject.printRandomColor();
return 0;
}
当我做rand() % 7
时,我一直得到6,但如果我做rand() % 6
我最终会得到随机数。是什么给了什么?
我在main()
中调用srand( static_cast<unsigned int>(time(0)));
答案 0 :(得分:0)
我注意到问题中显示的代码行为相同:
rand() % 7 // always shows 6
rand() % 14 // always shows 6 or 13
rand() % 21 // always shows 6, 13, or 20
问题很奇怪,似乎涉及到一种模式。根据有些人无法重现它的评论,我决定在基于Linux的机器上使用gcc编译代码并在macOS上进行操作; Linux似乎从我能说的正常行为,但macOS没有。我甚至尝试了完全不同的代码,只是确保它不是别的东西,但得到了相同的结果。
#include <cstdlib>
#include <iostream>
#include <ctime>
int main()
{
int min = 1;
int max = 7;
std::srand(std::time(0)); // use current time as seed for random generator
// int random_variable = std::rand() % max; // always returns 6
// int random_variable = std::rand() % (max - min) + min; // produces 'predictable' numbers based on the time.
int random_variable = RAND_MAX % std::rand() % (max-min) + min; // also returns predicate results based on the timing, except in reverse.
std::cout << "Random value on [0 " << RAND_MAX << "]: "
<< random_variable << '\n';
}
我能够从 rand()
获得看似随机的结果的唯一方法是:
RAND_MAX % std::rand() % (max-min) + min; // predictable based on timing
问题很奇怪,可能是Clang的错误;我对这里到底发生了什么感到茫然。我可能会建议使用rand()
之外的其他内容,例如评论中提到的<random>
库。
编辑:向Apple报告此错误后,回复:
Apple Developer Relations 2017年7月27日上午11:27
没有计划根据以下内容解决此问题:
std :: rand直接使用C库中的rand。兰德是众所周知的 记录下来要破坏(并且不会因人而改变) 取决于其具体行为)。
从手册页: RAND(3) BSD库函数手册
命名强> rand,rand_r,srand,sranddev - 糟糕的随机数发生器
<强>描述强> 这些接口被arc4random(3)废弃。
对于C ++中的良好伪随机数,请参阅C ++ 11。 例如:http://en.cppreference.com/w/cpp/numeric/random
根据此信息RAND()
已损坏并且无法修复 - 请使用其他随机数生成器。
答案 1 :(得分:0)
rand()
是terrible。 rand() % range
更糟糕。不要使用它。使用arc4random_uniform()
。
#include <iostream>
#include <cstdlib> // Needed for arc4random_uniform()
int main(int argc, char *argv[]) {
// Random number between 0 and 6.
std::cout << arc4random_uniform(7) << std::endl;
}
所以在你的情况下:
void printRandomColor()
{
int random_integer = arc4random_uniform(7);
cout << random_integer << endl;
}
如果需要可移植性,那么这是一个C ++标准示例。对我来说,这是不必要的更复杂,运行速度更慢,但嘿......这是C ++标准。
#include <iostream>
#include <random> // For std::random_device and std::uniform_int_distribution
int main() {
std::random_device randomizer;
std::uniform_int_distribution<int> distribution(0, 6);
// Random number between 0 and 6.
int random_integer = distribution(randomizer);
std::cout << random_integer << std::endl;
}
答案 2 :(得分:-5)
我想指出,你使用的是Random(Rand
)运算符,然后试图找出结果是否有一个Remainder(%
),结果将是Remainder ,这是你的奇怪数学来自。如果你想谷歌它,这被称为Modulo运算符或模数运算符,虽然你应该知道它在C#中实际上有一个稍微不同的名称,但StackTrace中有一篇关于它的帖子:
What does the '%' operator mean?
如果您打开Calc.exe
Windows程序,它将Scientific Mode
(Alt
+ 2
)列为Mod
。
具体而言,%
的运作方式为((x - (x / y)) * y)
上面的网址是我的回答的直接链接,我特别指出它与标准/
的完全不同,以及一个逐步模拟所有数学的长抽取示例,结果返回{{ 1}} 0
和%
1
/
,因为/
操作数roundUp()
%
roundDown()
来自%
我在帖子的其他答案中已经理解了。
我至少希望在这里得到这个答案,以便为本问题标题中提到的模运算符提供参考。
我没有专门发布这个本身的答案,但更多的是作为参考资料,以避免将来发布垃圾邮件。
如果这实际上是一个被发现的错误,那么这个问题将逐字逐句地逐个挑选,并且它会帮助所有相关人员在这里提供这个参考资料。
如果我不知道它已经被大多数语言命名为Modulo / Modulus,我会想知道他的意思是什么&#34; Modulo&#34;因为他从来没有在任何地方解释过%
的名字。
这个答案解决了这样一个事实:roundDown()
使用/
而roundUp()
使用line = line.replace('\n', '')
完成了一个引用的可编译示例,这些示例是在逐步扩展的逐步扩展中编写的然后我转换为C#。
我还想重申,正如我在评论中所提到的,我对xCode一无所知,我对C#有点熟悉,并在C#上下文中提供了这个问题标记的信息。