Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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 */
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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;
    }
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
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;
}