How to get current seed from C++ rand()?

前端 未结 8 739
名媛妹妹
名媛妹妹 2020-12-31 01:49

I generate a few thousand object in my program based on the C++ rand() function. Keeping them in the memory would be exhaustive. Is there a way to copy the CURRENT

8条回答
  •  北海茫月
    2020-12-31 02:15

    Is there a way to copy the CURRENT seed of rand() at any given time?

    What follows is an implementation-specific way to save and restore the pseudo-random number generator (PRNG) state that works with the C library on Ubuntu Linux (tested on 14.04 and 16.04).

    #include 
    #include 
    #include 
    
    using namespace std;
    
    constexpr size_t StateSize = 128;
    using RandState = array;
    
    void save(RandState& state) {
        RandState tmpState;
        char* oldState = initstate(1, tmpState.data(), StateSize);
        copy(oldState, oldState + StateSize, state.data());
        setstate(oldState);
    }
    
    void restore(RandState& state) {
        setstate(state.data());
    }
    
    int main() {
        cout << "srand(1)\n";
    
        srand(1);
    
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
    
        cout << "srand(1)\n";
    
        srand(1);
    
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
    
        cout << "save()\n";
    
        RandState state;
        save(state);
    
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
    
        cout << "restore()\n";
    
        restore(state);
    
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
        cout << "  rand(): " << rand() << '\n';
    }
    

    This relies on:

    1. the same PRNG being used by the C library to expose both rand() and random() interfaces, and
    2. some knowledge about the default initialization of this PRNG in the C library (128 bytes state).

    If run, this should output:

    srand(1)
      rand(): 1804289383
      rand(): 846930886
      rand(): 1681692777
      rand(): 1714636915
      rand(): 1957747793
      rand(): 424238335
      rand(): 719885386
      rand(): 1649760492
    srand(1)
      rand(): 1804289383
      rand(): 846930886
      rand(): 1681692777
      rand(): 1714636915
    save()
      rand(): 1957747793
      rand(): 424238335
      rand(): 719885386
      rand(): 1649760492
    restore()
      rand(): 1957747793
      rand(): 424238335
      rand(): 719885386
      rand(): 1649760492
    

    This solution can help in some cases (code that can't be changed, reproducing execution for debugging purpose, etc...), but it is obviously not recommended as a general one (e.g. use C++11 PRNG which properly support this).

提交回复
热议问题