OBJECT float_coerce(STATE, OBJECT value) { if(FIXNUM_P(value)) { return float_new(state, (double)N2I(value)); } else if(BIGNUM_P(value)) { return float_new(state, bignum_to_double(state, value)); } return value; }
static _rs_inline obj bignum_to_float(obj x) { mpz_t a; if( FIXNUM_P(x) ) { return make_float( (float) fx2int(x) ); } else if(BIGNUM_P(x)) { OBJ_TO_MPZ(a, x); return make_float(mpz_get_d(a)); } else if( LONG_INT_P(x) ) { return make_float(int_64_to_float( *((INT_64 *)PTR_TO_DATAPTR(x)) )); } scheme_error("bignum_to_float type not found for ~a", 1, x); return FALSE_OBJ; /* not reached */ }
int basic_raw_int_conv_p( obj a ) { if (FIXNUM_P( a )) { return 1; } if (LONG_INT_P( a )) { return 1; } #if FULL_NUMERIC_TOWER if (BIGNUM_P( a )) { return 1; } #endif return 0; }
int basic_raw_int_conv( obj a ) { if (FIXNUM_P( a )) { return fx2int( a ); } if (LONG_INT_P( a )) { INT_64 i = extract_int_64( a ); if (int_64_fit_in_32_q( i )) { return int_64_to_int_32( i ); } else { scheme_error( "long int ~s is out of range for a raw int", 1, a ); return 0; } } #if FULL_NUMERIC_TOWER else if (BIGNUM_P( a )) { mpz_t z; OBJ_TO_MPZ( z, a ); if (bignum_fit_in_32( z )) { return bignum_to_int( z ); } else { scheme_error( "bignum ~s is out of range for a raw int", 1, a ); return 0; } } #endif else { scheme_error( "cannot convert ~s to an exact integer", 1, a ); return 0; } }
/* * call-seq: * rand_state.seed(integer) * * From the GMP Manual: * * Set an initial seed value into state. * * The size of a seed determines how many different sequences of random numbers * that it's possible to generate. The “quality” of the seed is the randomness * of a given seed compared to the previous seed used, and this affects the * randomness of separate number sequences. The method for choosing a seed is * critical if the generated numbers are to be used for important applications, * such as generating cryptographic keys. * * Traditionally the system time has been used to seed, but care needs to be * taken with this. If an application seeds often and the resolution of the * system clock is low, then the same sequence of numbers might be repeated. * Also, the system time is quite easy to guess, so if unpredictability is * required then it should definitely not be the only source for the seed * value. On some systems there's a special device /dev/random which provides * random data better suited for use as a seed. */ VALUE r_gmprandstate_seed(VALUE self, VALUE arg) { MP_RANDSTATE *self_val; MP_INT *arg_val; mprandstate_get_struct(self,self_val); if (GMPZ_P(arg)) { mpz_get_struct(arg,arg_val); gmp_randseed(self_val, arg_val); } else if (FIXNUM_P(arg)) { gmp_randseed_ui(self_val, FIX2INT(arg)); } else if (BIGNUM_P(arg)) { mpz_temp_from_bignum(arg_val, arg); gmp_randseed(self_val, arg_val); } else { typeerror(ZXB); } return arg; }
UINT_32 basic_raw_uint_conv( obj a ) { if (FIXNUM_P(a)) { if (FX_LT( a, ZERO )) { scheme_error( "fixnum value ~s is negative, not a valid UINT_32", 1, a ); } return fx2int( a ); } else if (LONG_INT_P( a )) { INT_64 *p = (INT_64 *)PTR_TO_DATAPTR( a ); if ((p->digits[0] == 0) && (p->digits[1] == 0)) { return (p->digits[2] << 16) + p->digits[3]; } else { scheme_error( "longint value ~s is not a valid UINT_32", 1, a ); } #if FULL_NUMERIC_TOWER } else if (BIGNUM_P( a )) { mpz_t z; int cmp; OBJ_TO_MPZ( z, a ); cmp = mpz_sgn( z ); if (cmp < 0) { scheme_error( "bignum value ~s is negative, not a valid UINT_32", 1, a ); } if (cmp == 0) { return 0; } cmp = mpz_cmp_ui( z, 0xFFFFFFFFUL ); if (cmp > 0) { scheme_error( "bignum value ~s is too big for a UINT_32", 1, a ); } return mpz_get_ui( z ); #endif } else { scheme_error( "non-basic-integer value ~s is not a valid UINT_32", 1, a ); } return 0; }