Ticket #7152 (closed patched: fixed)

Opened 2 years ago

Last modified 2 years ago

statistical bias in get_random_long() with large ranges

Reported by: kaganar@… Owned by: devteam
Priority: minor Milestone: 1.8.2p2
Keywords: random get_random_long Cc:
Visibility: Public

Description

Great care is taken within get_random_long() (utils.c) to avoid any statistic biases introduced by limiting the range of genrand_31() via the reminder operator (%), however there seems to be a flaw as exemplified by:

th fdiv(lmath(add,iter(lnum(700),rand(1000000000))),700)

The gist of the code for get_random_long() that handles the actual random number generation seems to be:

x=high-low+1;
n_limit=ULONG_MAX-(ULONG_MAX % x);
do {
  n = genrand_int31();
} while (n >= n_limit);
return low + (n % x);

Presumably ULONG_MAX is 232-1, but genrand_int31() only results in numbers from 0 to 231-1, and since an earlier check guarantees n<=231-1, n_limit is always greater than 231-1 and the while-loop condition always fails. Presumably genrand_int32() should be used instead.

--Ian

Attachments

fix-rand.patch.txt (0.6 KB) - added by Luke 2 years ago.
Calls genrand_int32 instead of genrand_int31.

Change History

Changed 2 years ago by Luke

Calls genrand_int32 instead of genrand_int31.

Changed 2 years ago by ehearn

  • type changed from incoming to bug

Changed 2 years ago by raevnos

  • status changed from new to closed
  • type changed from bug to patched
  • resolution set to fixed
  • milestone set to 1.8.2p2

Um. Yes. I'm not sure why I made it use 31 bit ints in the first place, considering I pretty much lifted the code from MUX, which uses the MT's 32-bit generator.

Note: See TracTickets for help on using tickets.