Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1st call to rand(1.0) generates predictable values < 1e-4 for seeds in 0..<26844, unlike C++, python, D, ... #17467

Closed
timotheecour opened this issue Mar 23, 2021 · 0 comments · Fixed by #17468

Comments

@timotheecour
Copy link
Member

timotheecour commented Mar 23, 2021

Example

this shows that whatever (small) seed is picked, the 1st call to rand() gives a predictably small value < 1e-4, ie, skews the distribution.

import std/random
proc main()=
  let n = 100_000
  for i in 1..<n:
    randomize(i)
    let x = rand(1.0)
    doAssert x < 1e-4, $(x, i) # this passes for i in 0..<26844, but should not
main()

This is a bug, other languages don't have this issue:

nim: fails

by fail, I mean it produces skewed results
(see example above)

python: works

import random
for i in range(0,10):
  random.seed(a=i)
  print(random.random())

prints:

0.8444218515250481
0.13436424411240122
0.9560342718892494
0.23796462709189137
0.23604808973743452
0.6229016948897019
0.793340083761663
0.32383276483316237
0.2267058593810488
0.46300735781502145

D: works

import std.random,std.conv,std.stdio;
void main(){
  //auto seed = Clock.currTime().toUnixTime;
  for(int i=0;i<10;i++) {
    auto rnd = Random(i.to!int);
    uniform(0.0, 1.0, rnd).writeln;
  }
}

prints:

0.548814
0.417022
0.435995
0.550798
0.96703
0.221993
0.89286
0.0763083
0.873429
0.0103742

C++ works

#include <random>
#include <iostream>

void fn2() {
  // std::random_device rd;
  std::uniform_real_distribution<double> dist(0.0, 1.0);
  for (int i=0; i<10; ++i){
    std::mt19937 mt(i);
    std::cout << dist(mt) << "\n";
  }
}

int main() {
  // fn1();
  fn2();
  return 0;
}

prints:

0.592845
0.997185
0.185082
0.0707249
0.900621
0.0551801
0.947476
0.227339
0.0111144
0.364461

Additional Information

1.5.1 d6a1602

links

https://stackoverflow.com/questions/19665818/generate-random-numbers-using-c11-random-library
https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

this is also related to an issue I had previously raised: #8589

timotheecour added a commit to timotheecour/Nim that referenced this issue Mar 23, 2021
timotheecour added a commit to timotheecour/Nim that referenced this issue Mar 23, 2021
timotheecour added a commit to timotheecour/Nim that referenced this issue May 3, 2021
Araq pushed a commit that referenced this issue May 11, 2021
* fix #17467 1st call to rand is now non-skewed; allow passing 0 as seed

* changelog + fallback

* document behavior for seed == 0

* address comments

* _

* fix tests, disable kdtree

* re-enable kdtree with -d:nimLegacyRandomInitRand
PMunch pushed a commit to PMunch/Nim that referenced this issue Mar 28, 2022
nim-lang#17468)

* fix nim-lang#17467 1st call to rand is now non-skewed; allow passing 0 as seed

* changelog + fallback

* document behavior for seed == 0

* address comments

* _

* fix tests, disable kdtree

* re-enable kdtree with -d:nimLegacyRandomInitRand
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant