Value RandomState::random(Value arg) { if (fixnump(arg)) { long n = xlong(arg); if (n > 0) { mpz_t limit; mpz_init_set_si(limit, n); mpz_t result; mpz_init(result); mpz_urandomm(result, _state, limit); return normalize(result); } } else if (bignump(arg)) { Bignum * b = the_bignum(arg); if (b->plusp()) { mpz_t result; mpz_init(result); mpz_urandomm(result, _state, b->_z); return normalize(result); } } else if (single_float_p(arg)) { float f = the_single_float(arg)->_f; if (f > 0) { mpz_t fixnum_limit; mpz_init_set_si(fixnum_limit, MOST_POSITIVE_FIXNUM); mpz_t fixnum_result; mpz_init(fixnum_result); mpz_urandomm(fixnum_result, _state, fixnum_limit); double double_result = mpz_get_si(fixnum_result); double_result /= MOST_POSITIVE_FIXNUM; return make_value(new SingleFloat(double_result * f)); } } else if (double_float_p(arg)) { double d = the_double_float(arg)->_d; if (d > 0) { mpz_t fixnum_limit; mpz_init_set_si(fixnum_limit, MOST_POSITIVE_FIXNUM); mpz_t fixnum_result; mpz_init(fixnum_result); mpz_urandomm(fixnum_result, _state, fixnum_limit); double double_result = mpz_get_si(fixnum_result); double_result /= MOST_POSITIVE_FIXNUM; return make_value(new DoubleFloat(double_result * d)); } } return signal_type_error(arg, list3(S_or, list2(S_integer, list1(FIXNUM_ZERO)), list2(S_float, list1(FIXNUM_ZERO)))); }