~ubuntu-branches/ubuntu/trusty/ruby1.9/trusty

« back to all changes in this revision

Viewing changes to random.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2008-01-24 11:42:29 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20080124114229-jw2f87rdxlq6gp11
Tags: 1.9.0.0-2ubuntu1
* Merge from debian unstable, remaining changes:
  - Robustify check for target_os, fixing build failure on lpia.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
  random.c -
4
4
 
5
 
  $Author: matz $
6
 
  $Date: 2007-08-25 12:29:39 +0900 (土, 25  8月 2007) $
 
5
  $Author: akr $
 
6
  $Date: 2007-12-24 17:19:28 +0900 (Mon, 24 Dec 2007) $
7
7
  created at: Fri Dec 24 16:39:21 JST 1993
8
8
 
9
9
  Copyright (C) 1993-2007 Yukihiro Matsumoto
12
12
 
13
13
/* 
14
14
This is based on trimmed version of MT19937.  To get the original version,
15
 
contact <http://www.math.keio.ac.jp/~matumoto/emt.html>.
 
15
contact <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html>.
16
16
 
17
17
The original copyright notice follows.
18
18
 
145
145
}
146
146
 
147
147
/* generates a random number on [0,0xffffffff]-interval */
148
 
unsigned long
 
148
static unsigned long
149
149
genrand_int32(void)
150
150
{
151
151
    unsigned long y;
163
163
}
164
164
 
165
165
/* generates a random number on [0,1) with 53-bit resolution*/
166
 
double
 
166
static double
167
167
genrand_real(void)
168
168
169
169
    unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; 
188
188
#include <fcntl.h>
189
189
#endif
190
190
 
 
191
unsigned long
 
192
rb_genrand_int32(void)
 
193
{
 
194
    return genrand_int32();
 
195
}
 
196
 
 
197
double
 
198
rb_genrand_real(void)
 
199
{
 
200
    return genrand_real();
 
201
}
 
202
 
191
203
static VALUE saved_seed = INT2FIX(0);
192
204
 
193
205
static VALUE
204
216
          len = sizeof(VALUE);
205
217
          break;
206
218
      case T_BIGNUM:
207
 
          len = RBIGNUM(seed)->len * SIZEOF_BDIGITS;
 
219
          len = RBIGNUM_LEN(seed) * SIZEOF_BDIGITS;
208
220
          if (len == 0)
209
221
              len = 4;
210
222
          break;
223
235
    }
224
236
    else {
225
237
        int i, j;
226
 
        for (i = RBIGNUM(seed)->len-1; 0 <= i; i--) {
 
238
        for (i = RBIGNUM_LEN(seed)-1; 0 <= i; i--) {
227
239
            j = i * SIZEOF_BDIGITS / 4;
228
240
#if SIZEOF_BDIGITS < 4
229
241
            buf[j] <<= SIZEOF_BDIGITS * 8;
230
242
#endif
231
 
            buf[j] |= ((BDIGIT *)RBIGNUM(seed)->digits)[i];
 
243
            buf[j] |= RBIGNUM_DIGITS(seed)[i];
232
244
        }
233
245
    }
234
246
    while (1 < len && buf[len-1] == 0) {
263
275
    OBJSETUP(big, rb_cBignum, T_BIGNUM);
264
276
 
265
277
    seed_len = 4 * sizeof(long);
266
 
    big->sign = 1;
267
 
    big->len = seed_len / SIZEOF_BDIGITS + 1;
268
 
    digits = big->digits = ALLOC_N(BDIGIT, big->len);
269
 
    seed = (unsigned long *)big->digits;
 
278
    RBIGNUM_SET_SIGN(big, 1);
 
279
    rb_big_resize((VALUE)big, seed_len / SIZEOF_BDIGITS + 1);
 
280
    digits = RBIGNUM_DIGITS(big);
 
281
    seed = (unsigned long *)RBIGNUM_DIGITS(big);
270
282
 
271
 
    memset(digits, 0, big->len * SIZEOF_BDIGITS);
 
283
    memset(digits, 0, RBIGNUM_LEN(big) * SIZEOF_BDIGITS);
272
284
 
273
285
#ifdef S_ISCHR
274
286
    if ((fd = open("/dev/urandom", O_RDONLY
296
308
    seed[3] ^= (unsigned long)&seed;
297
309
 
298
310
    /* set leading-zero-guard if need. */
299
 
    digits[big->len-1] = digits[big->len-2] <= 1 ? 1 : 0;
 
311
    digits[RBIGNUM_LEN(big)-1] = digits[RBIGNUM_LEN(big)-2] <= 1 ? 1 : 0;
300
312
 
301
313
    return rb_big_norm((VALUE)big);
302
314
}
370
382
    struct RBignum *val;
371
383
    int i, len, boundary;
372
384
 
373
 
    len = (limit->len * SIZEOF_BDIGITS + 3) / 4;
 
385
    len = (RBIGNUM_LEN(limit) * SIZEOF_BDIGITS + 3) / 4;
374
386
    val = (struct RBignum *)rb_big_clone((VALUE)limit);
375
 
    val->sign = 1;
 
387
    RBIGNUM_SET_SIGN(val, 1);
376
388
#if SIZEOF_BDIGITS == 2
377
 
# define BIG_GET32(big,i) (((BDIGIT *)(big)->digits)[(i)*2] | \
378
 
                           ((i)*2+1 < (big)->len ? (((BDIGIT *)(big)->digits)[(i)*2+1] << 16) \
 
389
# define BIG_GET32(big,i) (RBIGNUM_DIGITS(big)[(i)*2] | \
 
390
                           ((i)*2+1 < RBIGNUM_DIGITS(big) ? (RBIGNUM_DIGITS(big)[(i)*2+1] << 16) \
379
391
                                                 : 0))
380
 
# define BIG_SET32(big,i,d) ((((BDIGIT *)(big)->digits)[(i)*2] = (d) & 0xffff), \
381
 
                             ((i)*2+1 < (big)->len ? (((BDIGIT *)(big)->digits)[(i)*2+1] = (d) >> 16) \
 
392
# define BIG_SET32(big,i,d) ((RBIGNUM_DIGITS(big)[(i)*2] = (d) & 0xffff), \
 
393
                             ((i)*2+1 < RBIGNUM_DIGITS(big) ? (RBIGNUM_DIGITS(big)[(i)*2+1] = (d) >> 16) \
382
394
                                                   : 0))
383
395
#else
384
396
    /* SIZEOF_BDIGITS == 4 */
385
 
# define BIG_GET32(big,i) (((BDIGIT *)(big)->digits)[i])
386
 
# define BIG_SET32(big,i,d) (((BDIGIT *)(big)->digits)[i] = (d))
 
397
# define BIG_GET32(big,i) (RBIGNUM_DIGITS(big)[i])
 
398
# define BIG_SET32(big,i,d) (RBIGNUM_DIGITS(big)[i] = (d))
387
399
#endif
388
400
  retry:
389
401
    mask = 0;
437
449
    rb_scan_args(argc, argv, "01", &vmax);
438
450
    switch (TYPE(vmax)) {
439
451
      case T_FLOAT:
440
 
        if (RFLOAT(vmax)->value <= LONG_MAX && RFLOAT(vmax)->value >= LONG_MIN) {
441
 
            max = (long)RFLOAT(vmax)->value;
 
452
        if (RFLOAT_VALUE(vmax) <= LONG_MAX && RFLOAT_VALUE(vmax) >= LONG_MIN) {
 
453
            max = (long)RFLOAT_VALUE(vmax);
442
454
            break;
443
455
        }
444
 
        if (RFLOAT(vmax)->value < 0)
445
 
            vmax = rb_dbl2big(-RFLOAT(vmax)->value);
 
456
        if (RFLOAT_VALUE(vmax) < 0)
 
457
            vmax = rb_dbl2big(-RFLOAT_VALUE(vmax));
446
458
        else
447
 
            vmax = rb_dbl2big(RFLOAT(vmax)->value);
 
459
            vmax = rb_dbl2big(RFLOAT_VALUE(vmax));
448
460
        /* fall through */
449
461
      case T_BIGNUM:
450
462
      bignum:
451
463
        {
452
464
            struct RBignum *limit = (struct RBignum *)vmax;
453
 
            if (!limit->sign) {
 
465
            if (!RBIGNUM_SIGN(limit)) {
454
466
                limit = (struct RBignum *)rb_big_clone(vmax);
455
 
                limit->sign = 1;
 
467
                RBIGNUM_SET_SIGN(limit, 1);
456
468
            }
457
469
            limit = (struct RBignum *)rb_big_minus((VALUE)limit, INT2FIX(1));
458
470
            if (FIXNUM_P((VALUE)limit)) {
459
471
                if (FIX2LONG((VALUE)limit) == -1)
460
 
                    return rb_float_new(genrand_real());
 
472
                    return DOUBLE2NUM(genrand_real());
461
473
                return LONG2NUM(limited_rand(FIX2LONG((VALUE)limit)));
462
474
            }
463
475
            return limited_big_rand(limit);
474
486
    }
475
487
 
476
488
    if (max == 0) {
477
 
        return rb_float_new(genrand_real());
 
489
        return DOUBLE2NUM(genrand_real());
478
490
    }
479
491
    if (max < 0) max = -max;
480
492
    val = limited_rand(max-1);