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

.pick on large ranges gives unexpected results on Windows only #6059

Open
p6rt opened this issue Feb 5, 2017 · 4 comments
Open

.pick on large ranges gives unexpected results on Windows only #6059

p6rt opened this issue Feb 5, 2017 · 4 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Feb 5, 2017

Migrated from rt.perl.org#130723 (status was 'open')

Searchable as RT130723$

@p6rt
Copy link
Author

p6rt commented Feb 5, 2017

From @mscha

On my self-compiled Linux build of Rakudo Star 2017.01​:

% perl6 -e 'say (-524288..^524288).pick(50)'
(445052 -427 442649 66610 133030 238409 -250288 438259 508787 423778
90030 28568 -372417 143522 -335109 -156474 -395940 -124515 517779 398864
-494020 -303173 -4646 253705 -263919 204704 328943 -230539 276553
-142475 -311381 -224414 410534 -58726 -27584 -135264 -222462 79964
-177401 -413056 -279021 -445158 -161601 61337 -101262 -66850 -285553
-506522 366891 289163)

This looks pretty normal.

But on my Windows machine, using the 64-bit version of Rakudo Star
2017.01, downloaded from http://rakudo.org/downloads/star/ , I get​:

% perl6 -e 'say (-524288..^524288).pick(50)'
(-504365 -504962 -520900 -503012 -504515 -514927 -524063 -511982 -503130
-511610 -515842 -518903 -505137 -513172 -504845 -512334 -513608 -518507
-512159 -508672 -492893 -503150 -501718 -515295 -495598 -513483 -507283
-493687 -494653 -498803 -497266 -519193 -510278 -503827 -501717 -514772
-507593 -500763 -509913 -509046 -523590 -516283 -499038 -501134 -499195
-496352 -495618 -522092 -504550 -498746)

I.e., I consistently get numbers close to the bottom end of the range.

@p6rt
Copy link
Author

p6rt commented Feb 6, 2017

From @nwc10

OK, this is a bit of guessing, and I would like to think that I've guessed
wrongly because someone else *should* have hit this before...

On Sun, Feb 05, 2017 at 03​:21​:12PM -0800, Michael Schaap wrote​:

# New Ticket Created by Michael Schaap
# Please include the string​: [perl #​130723]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=130723 >

On my self-compiled Linux build of Rakudo Star 2017.01​:

% perl6 -e 'say (-524288..^524288).pick(50)'
(445052 -427 442649 66610 133030 238409 -250288 438259 508787 423778
90030 28568 -372417 143522 -335109 -156474 -395940 -124515 517779 398864
-494020 -303173 -4646 253705 -263919 204704 328943 -230539 276553
-142475 -311381 -224414 410534 -58726 -27584 -135264 -222462 79964
-177401 -413056 -279021 -445158 -161601 61337 -101262 -66850 -285553
-506522 366891 289163)

This looks pretty normal.

But on my Windows machine, using the 64-bit version of Rakudo Star
2017.01, downloaded from http://rakudo.org/downloads/star/ , I get​:

% perl6 -e 'say (-524288..^524288).pick(50)'
(-504365 -504962 -520900 -503012 -504515 -514927 -524063 -511982 -503130
-511610 -515842 -518903 -505137 -513172 -504845 -512334 -513608 -518507
-512159 -508672 -492893 -503150 -501718 -515295 -495598 -513483 -507283
-493687 -494653 -498803 -497266 -519193 -510278 -503827 -501717 -514772
-507593 -500763 -509913 -509046 -523590 -516283 -499038 -501134 -499195
-496352 -495618 -522092 -504550 -498746)

I.e., I consistently get numbers close to the bottom end of the range.

Windows. Random numbers.

3rdparty/libtommath/bn_mp_rand.c has​:

  /* first place a random non-zero digit */
  do {
  d = ((mp_digit) abs (MP_GEN_RANDOM())) & MP_MASK;
  } while (d == 0);

  if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
  return res;
  }

  while (--digits > 0) {
  if ((res = mp_lshd (a, 1)) != MP_OKAY) {
  return res;
  }

  if ((res = mp_add_d (a, ((mp_digit) abs (MP_GEN_RANDOM())), a)) != MP_OKAY) {
  return res;
  }
  }

3rdparty/libtommath/tommath.h has​:

/* use arc4random on platforms that support it */
#ifdef MP_USE_ALT_RAND
  #define MP_GEN_RANDOM() arc4random()
#else
  #define MP_GEN_RANDOM() rand()
#endif

#define MP_DIGIT_BIT DIGIT_BIT
#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
#define MP_DIGIT_MAX MP_MASK

and

#ifdef MP_31BIT
  /* this is an extension that uses 31-bit digits */
  #define DIGIT_BIT 31
#else
  /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
  #define DIGIT_BIT 28
  #define MP_28BIT
#endif

Which I think means that it's either using 28 or 31 bit "digits".

IIRC rand() on Win32 only returns 15 bit values.
Most *nix systems return 31 bit values.
ANSI C only mandates 15 bit as a minimum.

If so, this third-party code is buggy.

But if that's true, why on Earth has no-one else hit this before?

Nicholas Clark

@p6rt
Copy link
Author

p6rt commented Feb 6, 2017

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Feb 6, 2017

From @geekosaur

On Mon, Feb 6, 2017 at 3​:31 PM, Nicholas Clark <nick@​ccl4.org> wrote​:

OK, this is a bit of guessing, and I would like to think that I've guessed
wrongly because someone else *should* have hit this before...

You'd be surprised. Verifying randomness is fairly tricky... and Perl 3
went through this on a bunch of platforms where the random bits needed to
be tuned per platform (before there was any sort of standardization between
unixlikes, not to mention Windows, VMS, ...). Nobody noticed for several
years that the randbits were wrong on various platforms --- and not all of
those platforms were obscure.

--
brandon s allbery kf8nh sine nomine associates
allbery.b@​gmail.com ballbery@​sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

@p6rt p6rt added the Bug label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant