Reputation: 2057
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 );
}
Upvotes: 0
Views: 282
Reputation: 10238
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.
Upvotes: 1