diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2025-03-23 13:25:57 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2025-03-23 13:25:57 -0700 |
commit | 4b7a74d693fff116b5a8cc0820788004453278f2 (patch) | |
tree | 68fce90b4250a1a22fca9be0b39460170ab792e5 | |
parent | 8999e74125d1ca2f526d25f437848861cdc19024 (diff) | |
download | txr-4b7a74d693fff116b5a8cc0820788004453278f2.tar.gz txr-4b7a74d693fff116b5a8cc0820788004453278f2.tar.bz2 txr-4b7a74d693fff116b5a8cc0820788004453278f2.zip |
rand: rearrange code to test fixnump first.
* rand.c (random): The fixnump is going to come up more often
than bignum, and is also fast to test for since fixnums are
identified by just the tag in value word.
-rw-r--r-- | rand.c | 92 |
1 files changed, 46 insertions, 46 deletions
@@ -367,52 +367,7 @@ val random(val state, val modulus) cobj_handle(self, state, random_state_cls)); mp_int *m; - if (bignump(modulus) && !mp_isneg(m = mp(modulus))) { - ucnum bits = mp_count_bits(m) - mp_is_pow_two(m); - ucnum rands_needed = (bits + 32 - 1) / 32; - ucnum msb_rand_bits = bits % 32; - rand32_t msb_rand_mask = convert(rand32_t, -1) >> (msb_rand_bits - ? 32 - msb_rand_bits - : 0); - val out = make_bignum(); - mp_int *om = mp(out); - - for (;;) { - ucnum i; - for (i = 0; i < rands_needed; i++) { - rand32_t rnd = rand32(r); - mp_err mpe = MP_OKAY; -#if MP_DIGIT_SIZE >= 4 - if (i > 0) - mpe = mp_mul_2d(om, 32, om); - else - rnd &= msb_rand_mask; - if (mpe == MP_OKAY) - mpe = mp_add_d(om, rnd, om); -#else - if (i > 0) - mpe = mp_mul_2d(om, 16, om); - else - rnd &= msb_rand_mask; - if (mpe == MP_OKAY) - mpe = mp_add_d(om, rnd & 0xFFFF, om); - if (mpe == MP_OKAY) - mpe = mp_mul_2d(om, 16, om); - if (mpe == MP_OKAY) - mp_add_d(om, rnd >> 16, om); -#endif - if (mpe != MP_OKAY) - do_mp_error(self, mpe); - } - if (mp_cmp(om, m) != MP_LT) { - mp_zero(om); - continue; - } - break; - } - - return normalize(out); - } else if (fixnump(modulus)) { + if (fixnump(modulus)) { cnum m = c_num(modulus, self); if (m == 1) { return zero; @@ -583,6 +538,51 @@ val random(val state, val modulus) default: break; } + } else if (bignump(modulus) && !mp_isneg(m = mp(modulus))) { + ucnum bits = mp_count_bits(m) - mp_is_pow_two(m); + ucnum rands_needed = (bits + 32 - 1) / 32; + ucnum msb_rand_bits = bits % 32; + rand32_t msb_rand_mask = convert(rand32_t, -1) >> (msb_rand_bits + ? 32 - msb_rand_bits + : 0); + val out = make_bignum(); + mp_int *om = mp(out); + + for (;;) { + ucnum i; + for (i = 0; i < rands_needed; i++) { + rand32_t rnd = rand32(r); + mp_err mpe = MP_OKAY; +#if MP_DIGIT_SIZE >= 4 + if (i > 0) + mpe = mp_mul_2d(om, 32, om); + else + rnd &= msb_rand_mask; + if (mpe == MP_OKAY) + mpe = mp_add_d(om, rnd, om); +#else + if (i > 0) + mpe = mp_mul_2d(om, 16, om); + else + rnd &= msb_rand_mask; + if (mpe == MP_OKAY) + mpe = mp_add_d(om, rnd & 0xFFFF, om); + if (mpe == MP_OKAY) + mpe = mp_mul_2d(om, 16, om); + if (mpe == MP_OKAY) + mp_add_d(om, rnd >> 16, om); +#endif + if (mpe != MP_OKAY) + do_mp_error(self, mpe); + } + if (mp_cmp(om, m) != MP_LT) { + mp_zero(om); + continue; + } + break; + } + + return normalize(out); } uw_throwf(numeric_error_s, lit("~a: invalid modulus ~s"), |