0

I am generating a random number for a particular seed ...So I have a property called seed which I allow the user to set. I give him two options: reset and trigger. The reset will re start the generation of random numbers. And trigger will generate the next random number. The pseudo code is somewhat like

::setSeed( unsigned &  seed )
{
   m_seed = seed
}

::reset()
{
   m_seed = getcurrentseed()
   srand(m_seed);
}

::trigger()
{
    raValue = minValue + ( rand() % (maxValue-minValue+1) );
}

For a particular seed if I generate say 5 random values 5 times ..sometimes I see a value missing in one of the sets . What could be the reason ?

For eg.

seed(5)
rand()
rand()
rand()
seed(5)
rand()
rand()
rand()

After the second seed(5) call, sometimes I get a different sequence of numbers or I miss a number from the previous sequence

void RandomNodeLogic::process(  SingleInputValueGetters const& singleInputValueGetters
                                   , MultiInputValueGetters const& /*multiInputValueGetters*/
                                   , OutputValueKeepers const& /*outputValueKeepers */
                                   , OutputValueSetters const& outputValueSetters )
{
    // get the seed and generate the random number 
    bool doRandom( false );
    int maxValue=  getMaxValue().getAs<int>();
    int minValue = getMinValue().getAs<int>();
    int newValue=0;

    if(minValue > maxValue)
    {
        setMaxValue(minValue);
        setMinValue(maxValue);
        maxValue=  getMaxValue().getAs<int>();
        minValue = getMinValue().getAs<int>();

    }



    SingleInputValueGetters::const_iterator it = singleInputValueGetters.begin();
    for( ; it != singleInputValueGetters.end(); ++it)
    {
        SlotID id = it->first;
        const SlotValue* value = it->second();
        if(!value)
        {
            continue;
        }

        if ( id == RTT::LogicNetwork::RandomNode::nextValuesSlotID )
        {
            doRandom = value->getAs<bool>();
            newValue = minValue + ( rand() % (maxValue-minValue+1) );  // read the value from the next input slot
            setRandomValue( ::convertToSlotValue( m_genValue.m_attrType, newValue ) );
        }

        else if ( id == RTT::LogicNetwork::RandomNode::resetValuesSlotID )
        {
            if ( value->getAs<bool>() )
            {
                doRandom = value->getAs<bool>();
                setSeed(m_seed);
                newValue = minValue + ( rand() % (maxValue-minValue+1) );
                setRandomValue( ::convertToSlotValue( m_genValue.m_attrType, newValue ) );

            }

        }

    }

    if(!m_genValue.empty() && doRandom)
    {
        outputValueSetters.find( RTT::LogicNetwork::RandomNode::outputValuesSlotID)->second( m_genValue.getAs<int>() ) ;
        RTT_LOG_INFO( QString("Random Number: %1").arg( m_genValue.getAs<int>() ));
    }

    if(!doRandom)
    {
        if(m_genValue.empty())
        {
            srand(1);
            m_genValue = 0;
        }
        getAssociatedNode()->sleep();
    }

}



 void RandomNodeLogic::setSeed( const SlotValue& seed )
    {
        SlotValue oldValue = m_seed;
        m_seed = seed;
        srand(m_seed.getAs<unsigned int>());
        modifiablePropertyValueChanged( RTT::LogicNetwork::RandomNode::seedPropertyID, m_seed, oldValue );


}
Wolf
  • 9,679
  • 7
  • 62
  • 108
sameer karjatkar
  • 2,017
  • 4
  • 23
  • 43
  • 3
    Are you using C or C++? They are not the same language, and you probably shouldn't be using `srand()` at all in C++. – George Jan 18 '17 at 11:11
  • 7
    For us to know the reason, you need to drop the pseudo code and show us the **exact code**. – dbush Jan 18 '17 at 11:12
  • @KeineLust seed(5) rand() rand() rand() seed(5) rand() rand() rand() – sameer karjatkar Jan 18 '17 at 11:13
  • 5
    Give us real code that replicates the problem. Your code to replicate the problem calls some function called `seed` and some function called `rand` neither of whose code is shown. You show some code called `trigger` that is not called. And so on. We need to replicate the problem to understand it. – David Schwartz Jan 18 '17 at 11:21
  • It sounds like you *want* to call `srand()` more than once to restart the `rand()` values at the same place in the sequence. It also sounds like you call `srand()` either never, or only once. – quamrana Jan 18 '17 at 11:24
  • I want the user to select a seed and then generate a random number . For eg ..I want to generate a RGB value between 0 and 255 for a seed 10 . – sameer karjatkar Jan 18 '17 at 11:25
  • 5
    BTW, in `rand() % minValue + ( rand() % (maxValue-minValue+1) )`, the 2 calls of `rand()` can be done in any order each time. – Jarod42 Jan 18 '17 at 11:28
  • 2
    `m_seed = getcurrentseed()` what does that do? I thought `m_seed` *was* the current seed? – Galik Jan 18 '17 at 11:38
  • @DavidSchwartz: `srand` and `rand` are declared in ``, and are part of the C++ Standard Library. (We still need to see the code). – Martin Bonner supports Monica Jan 18 '17 at 11:40
  • @Galik when the user sets a seed it is assigned to member variable m_seed – sameer karjatkar Jan 18 '17 at 11:40
  • As I understand it, @Galik talks about `::reset()` but you seem not. Very confusing. Is it even *your* code? Where are all the return values and the semicolons?? Is it really C or C++??? – Wolf Jan 18 '17 at 11:45
  • 1
    @Jarod42 but they won't be. Of course, no specific order is guaranteed. But re-rolling the dice on it at runtime requires completely insane code, it would take a compiler way more effort to intentionally compile it in such an actively evil way than just choosing some order. – harold Jan 18 '17 at 11:45
  • @harold I don't think so. For example, it may inline the code. And in one place, `minValue` may already be in a register and in another place it might not be. That could cause differences in code generation that change the order of evaluation. – David Schwartz Jan 18 '17 at 11:54

1 Answers1

1

All informations you gave so far tell me that you are trying to write a C++ class wrapper for C random functions. Even if this wrapper is a class that can be instantiated multiple times, the underlying C functions access only one state. That's why you have to ensure that nobody else is using an instance of this wrapper class.

That's why it is a bad idea, to wrap C's random functions with a C++ class. As an C++ exercise in random try to implement your own random class, it's not as hard as it seems.

Community
  • 1
  • 1
Wolf
  • 9,679
  • 7
  • 62
  • 108
  • If I set the seed in a global namespace ..should it suffice – sameer karjatkar Jan 20 '17 at 11:14
  • @sameerkarjatkar having your question here indicates that it will most probably not suffice. I really think that your question is still to vague to get a helpful answer. Wouldn't it be possible to break down your use case as to show what part of your solution makes the problem? If I, and others, read *`RandomNodeLogic::process`* it means not more than *`MyThing::doIt`* also the parameter types are *not helpful* for us to guess what you are trying to achieve. But your assumption that `srand(5);rand();rand();rand();srand(5); rand();rand();rand();` gives `a,b,c,a,b,c` makes sense (in a clean env) – Wolf Jan 20 '17 at 13:52