rand()根据xcode中的模数不给出随机数

时间:2017-06-25 00:32:48

标签: c++ xcode

我有一个包含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)));

3 个答案:

答案 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()terriblerand() % 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 ModeAlt + 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#上下文中提供了这个问题标记的信息。