Changeset 31352 in project


Ignore:
Timestamp:
09/09/14 18:11:06 (5 years ago)
Author:
sjamaan
Message:

numbers: Convert horrible randomizer to core naming convention

Location:
release/4/numbers/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • release/4/numbers/trunk/numbers-c.c

    r31351 r31352  
    304304  bignum_destructive_copy (bignum, result);
    305305  return (result);
    306 }
    307 
    308 #define fix_randomize  C_randomize
    309 #define fix_random C_random_fixnum
    310 
    311 /*
    312  * This random number generator is very simple. Probably too simple...
    313  */
    314 static C_word
    315 big_randomize(C_word bignum)
    316 {
    317   bignum_type big;
    318   C_word seed = 0;
    319   bignum_digit_type * scan, * end;
    320 
    321   big = big_of(bignum);
    322   scan = (BIGNUM_START_PTR (big));
    323   end = scan + BIGNUM_LENGTH(big);
    324   /* What a cheap way to initialize the random generator. I feel dirty! */
    325   while (scan < end)
    326     seed ^= *scan++;
    327 
    328   srand(C_unfix(seed));
    329   return C_SCHEME_UNDEFINED;
    330 }
    331 
    332 static void
    333 big_random(C_word c, C_word self, C_word k, C_word max)
    334 {
    335   bignum_type bigmax;
    336   bignum_type result;
    337   bignum_length_type randlen, max_len, max_bits;
    338   bignum_digit_type max_top_digit, d;
    339   bignum_digit_type * scan, * end;
    340  
    341   bigmax = big_of(max);
    342 
    343   max_len = BIGNUM_LENGTH(bigmax);
    344   max_top_digit = d = BIGNUM_REF(bigmax, max_len - 1);
    345  
    346   max_bits = (max_len - 1) * BIGNUM_DIGIT_LENGTH;
    347   while(d) {
    348     max_bits++;
    349     d >>= 1;
    350   }
    351   /* Subtract/add one because we don't want zero to be over-represented */
    352   randlen = (((double)rand())/(RAND_MAX + 1.0) * (double)(max_bits - 1));
    353   randlen = BIGNUM_BITS_TO_DIGITS(randlen + 1);
    354  
    355   result = bignum_allocate(randlen, BIGNUM_NEGATIVE_P(bigmax));
    356   scan = BIGNUM_START_PTR(result);
    357   end = scan + randlen - 1; /* Go to just before the end */
    358   while(scan < end)
    359     *scan++ = (((double)rand())/(RAND_MAX + 1.0) * (double)BIGNUM_RADIX);
    360   /*
    361    * Last word is special when length is max_len: It must be less than
    362    * max's most significant digit, instead of BIGNUM_RADIX.
    363    */
    364   if (max_len == randlen)
    365     *scan = (((double)rand())/(RAND_MAX + 1.0) * (double)max_top_digit);
    366   else
    367     *scan = (((double)rand())/(RAND_MAX + 1.0) * (double)BIGNUM_RADIX);
    368 
    369   result = bignum_trim(result); 
    370   C_return_bignum(k, result);
    371306}
    372307
     
    16001535static void bignum_actual_shift(C_word c, C_word self, C_word result);
    16011536static void bignum_abs_2(C_word c, C_word self, C_word result);
     1537static void bignum_random_2(C_word c, C_word self, C_word result);
    16021538
    16031539/* Eventually this will probably need to be integrated into C_2_plus. */
     
    25432479  C_kontinue(k, result);
    25442480}
     2481
     2482/*
     2483 * This random number generator is very simple. Probably too simple...
     2484 */
     2485C_word C_ccall
     2486C_u_i_bignum_randomize(C_word bignum)
     2487{
     2488  C_word seed = 0,
     2489         *scan = C_bignum_digits(bignum),
     2490         *end = scan + C_bignum_size(bignum);
     2491
     2492  /* What a cheap way to initialize the random generator. I feel dirty! */
     2493  while (scan < end)
     2494    seed ^= *scan++;
     2495
     2496  srand(seed);
     2497  return C_SCHEME_UNDEFINED;
     2498}
     2499
     2500void C_ccall
     2501C_u_bignum_random(C_word c, C_word self, C_word k, C_word max)
     2502{
     2503  C_word k2, kab[C_SIZEOF_CLOSURE(4)], *ka = kab, size,
     2504         max_len, max_bits, max_top_digit, d, negp;
     2505
     2506  max_len = C_bignum_size(max);
     2507  max_top_digit = d = C_bignum_digits(max)[max_len - 1];
     2508 
     2509  max_bits = (max_len - 1) * C_BIGNUM_DIGIT_LENGTH;
     2510  while(d) {
     2511    max_bits++;
     2512    d >>= 1;
     2513  }
     2514  /* Subtract/add one because we don't want zero to be over-represented */
     2515  size = ((double)rand())/(RAND_MAX + 1.0) * (double)(max_bits - 1);
     2516  size = C_fix(C_BIGNUM_BITS_TO_DIGITS(size + 1));
     2517
     2518  negp = C_mk_bool(C_bignum_negativep(max));
     2519  k2 = C_closure(&ka, 3, (C_word)bignum_random_2, k, C_fix(max_top_digit), C_fix(max_len));
     2520  C_allocate_bignum(3, (C_word)NULL, k2, size, negp, C_SCHEME_FALSE);
     2521}
     2522
     2523static void
     2524bignum_random_2(C_word c, C_word self, C_word result)
     2525{
     2526  C_word k = C_block_item(self, 1),
     2527         max_top_digit = C_unfix(C_block_item(self, 2)),
     2528         max_len = C_unfix(C_block_item(self, 3)),
     2529         *scan = C_bignum_digits(result),
     2530         *end = scan + C_bignum_size(result); /* Go to just before the end. */
     2531
     2532  while(scan < end)
     2533    *scan++ = ((double)rand())/(RAND_MAX + 1.0) * (double)((C_word)1 << C_BIGNUM_DIGIT_LENGTH);
     2534  /*
     2535   * Last word is special when length is max_len: It must be less than
     2536   * max's most significant digit, instead of BIGNUM_RADIX.
     2537   */
     2538  if (max_len == C_bignum_size(result))
     2539    *scan = ((double)rand())/(RAND_MAX + 1.0) * (double)max_top_digit;
     2540  else
     2541    *scan = ((double)rand())/(RAND_MAX + 1.0) * (double)((C_word)1 << C_BIGNUM_DIGIT_LENGTH);
     2542
     2543  C_bignum_destructive_trim(result);
     2544  C_kontinue(k, C_bignum_normalize(result));
     2545}
  • release/4/numbers/trunk/numbers-c.h

    r31351 r31352  
    235235C_word C_u_i_bignum_cmp(C_word x, C_word y);
    236236void C_ccall C_u_bignum_abs(C_word c, C_word self, C_word k, C_word big);
     237C_word C_ccall C_u_i_bignum_randomize(C_word bignum);
     238void C_ccall C_u_bignum_random(C_word c, C_word self, C_word k, C_word max);
    237239
    238240void C_ccall C_digits_to_integer(C_word c, C_word self, C_word k, C_word n, C_word start, C_word end, C_word radix, C_word negp);
  • release/4/numbers/trunk/numbers.scm

    r31351 r31352  
    198198(define-inline (%subchar s i) (##core#inline "C_subchar" s i))
    199199
    200 (define-inline (%fix-randomize n) (##core#inline "fix_randomize" n))
     200(define-inline (%fix-randomize n) (##core#inline "C_randomize" n))
    201201(define-inline (%big-randomize n) (##core#inline "big_randomize" n))
    202202
    203 (define-inline (%fix-random n) (##core#inline "fix_random" n))
    204 (define %big-random (##core#primitive "big_random"))
     203(define-inline (%fix-random n) (##core#inline "C_random_fixnum" n))
     204(define %big-random (##core#primitive "C_u_bignum_random"))
    205205
    206206
Note: See TracChangeset for help on using the changeset viewer.