Karim BELABAS on Thu, 1 Oct 1998 18:34:13 +0200 (MET DST)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

limit number of random


[Kiyoshi Ohgishi writes:]
> I want get large random number.
> 
> But version 2.0.4.alpha,
> 
> ? random(2^100)
>   ***   invalid bound in random.
> 
> I think "random" work at version 2.0.alpha

random() never produced anything bigger than 2^31-1. But I agree this could
be useful. The following patch does what you want (and improves a bit the
previous version even if the bound is < 2^31). Apply it to 2.0.11, or wait
for 2.0.12 to be released.

Cheers,

  Karim.

*** src/basemath/bibli2.c.orig	Mon Sep 28 14:29:45 1998
--- src/basemath/bibli2.c	Thu Oct  1 18:27:47 1998
***************
*** 652,680 ****
  long
  mymyrand()
  {
! #ifdef LONG_IS_64BIT
!   if (BITS_IN_RANDOM==64)
!     pari_randseed = 1000000000000654397*pari_randseed + 12347;
!   else
!     pari_randseed = (1000276549*pari_randseed + 12347) % 2147483648;
  #else
!   pari_randseed = 1000276549*pari_randseed + 12347;
!   if (pari_randseed<0) pari_randseed &= (~HIGHBIT);
  #endif
    return pari_randseed;
  }
  
  GEN
  genrand(GEN N)
  {
!   long av,tetpil;
  
    if (!N) return stoi(mymyrand());
!   if (typ(N)!=t_INT || signe(N)<=0 || is_bigint(N))
!     err(talker,"invalid bound in random");
  
!   av = avma; N = mulis(N, mymyrand()); tetpil = avma;
!   return gerepile(av,tetpil, shifti(N, -(BITS_IN_RANDOM-1)));
  }
  
  GEN
--- 652,699 ----
  long
  mymyrand()
  {
! #if BITS_IN_RANDOM == 64
!   pari_randseed = (1000000000000654397*pari_randseed + 12347) & ~HIGHBIT;
  #else
!   pari_randseed = (1000276549*pari_randseed + 12347) & 0x7fffffff;
  #endif
    return pari_randseed;
  }
  
+ GEN muluu(ulong x, ulong y);
+ 
+ #define GLUE(hi, lo) (((hi) << BITS_IN_HALFULONG) | (lo))
+ static ulong
+ gp_rand()
+ {
+   return GLUE(((mymyrand()>>12)&LOWMASK), ((mymyrand()>>12)&LOWMASK));
+ }
+ 
  GEN
  genrand(GEN N)
  {
!   long lx,i;
!   GEN x;
  
    if (!N) return stoi(mymyrand());
!   if (typ(N)!=t_INT || signe(N)<=0) err(talker,"invalid bound in random");
  
!   lx = lgefint(N); x = new_chunk(lx);
!   for (i=2; i<lx; i++)
!   {
!     long av = avma, n = N[i]; 
!     ulong r = gp_rand();
!     if (i < lx-1) n++; else if (!n) r = 0;
!     if (n) { GEN p1 = muluu(n,r); r = (lgefint(p1)<=3)? 0: p1[2]; }
!     avma = av; x[i] = r;
!     if (r < (ulong)N[i]) break;
!   }
!   for (i++; i<lx; i++) x[i] = gp_rand();
!   i=2; while (i<lx && !x[i]) i++;
!   i -= 2; x += i; lx -= i;
!   x[1] = evalsigne(lx>2) | evallgefint(lx);
!   x[0] = evaltyp(t_INT) | evallg(lx);
!   avma = (long)x; return x;
  }
  
  GEN
*** src/kernel/none/mp.c.orig	Wed Sep 30 19:03:00 1998
--- src/kernel/none/mp.c	Thu Oct  1 17:45:41 1998
***************
*** 648,653 ****
--- 648,671 ----
    z[2]=p1; return z;
  }
  
+ GEN
+ muluu(ulong x, ulong y)
+ {
+   long p1;
+   GEN z;
+   LOCAL_HIREMAINDER;
+ 
+   if (!x || !y) return gzero;
+   p1 = mulll(x,y);
+   if (hiremainder)
+   {
+     z=cgeti(4); z[1] = evalsigne(1) | evallgefint(4);
+     z[2]=hiremainder; z[3]=p1; return z;
+   }
+   z=cgeti(3); z[1] = evalsigne(1) | evallgefint(3);
+   z[2]=p1; return z;
+ }
+ 
  /* assume ny > 0 */
  #ifdef INLINE
  INLINE
--
Karim Belabas                    email: Karim.Belabas@math.u-psud.fr
Dep. de Mathematiques, Bat. 425
Universite Paris-Sud             Tel: (00 33) 1 69 15 57 48
F-91405 Orsay (France)           Fax: (00 33) 1 69 15 60 19
--
PARI/GP Home Page: http://pari.home.ml.org