| 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