赞 54
VIP 0
好人卡 3
积分 46
经验 31992
最后登录 2024-11-7
在线时间 1206 小时
Lv3.寻梦者
梦石 0
星屑 4598
在线时间 1206 小时
注册时间 2016-4-7
帖子 982
本帖最后由 shitake 于 2018-1-30 21:09 编辑
rb_define_global_function( "srand" , rb_f_srand, -1 ) ;
rb_define_global_function( "rand" , rb_f_rand, -1 ) ;
rb_cRandom = rb_define_class( "Random" , rb_cObject) ;
rb_define_alloc_func( rb_cRandom, random_alloc) ;
rb_define_method( rb_cRandom, "initialize" , random_init, -1 ) ;
rb_define_method( rb_cRandom, "rand" , random_rand, -1 ) ;
rb_define_global_function( "srand" , rb_f_srand, -1 ) ;
rb_define_global_function( "rand" , rb_f_rand, -1 ) ;
rb_cRandom = rb_define_class( "Random" , rb_cObject) ;
rb_define_alloc_func( rb_cRandom, random_alloc) ;
rb_define_method( rb_cRandom, "initialize" , random_init, -1 ) ;
rb_define_method( rb_cRandom, "rand" , random_rand, -1 ) ;
这是ruby 的random.c里最后定义Random这个类的时候的代码
其中rb_define_global_function("rand", rb_f_rand, -1); 复制代码 这句就是定义了Kernel的rand函数
而这个rb_f_rand 长这样:
static VALUE
rb_f_rand( int argc, VALUE *argv, VALUE obj)
{
VALUE vmax;
rb_random_t *rnd = rand_start( &default_rand) ;
if ( rb_check_arity( argc, 0 , 1 ) && !NIL_P( vmax = argv[ 0 ] ) ) {
VALUE v = rand_range( Qnil, rnd, vmax) ;
if ( v != Qfalse) return v;
vmax = rb_to_int( vmax) ;
if ( vmax != INT2FIX( 0 ) ) {
v = rand_int( Qnil, rnd, vmax, 0 ) ;
if ( !NIL_P( v) ) return v;
}
}
return DBL2NUM( genrand_real( &rnd->mt) ) ;
}
static VALUE
rb_f_rand( int argc, VALUE *argv, VALUE obj)
{
VALUE vmax;
rb_random_t *rnd = rand_start( &default_rand) ;
if ( rb_check_arity( argc, 0 , 1 ) && !NIL_P( vmax = argv[ 0 ] ) ) {
VALUE v = rand_range( Qnil, rnd, vmax) ;
if ( v != Qfalse) return v;
vmax = rb_to_int( vmax) ;
if ( vmax != INT2FIX( 0 ) ) {
v = rand_int( Qnil, rnd, vmax, 0 ) ;
if ( !NIL_P( v) ) return v;
}
}
return DBL2NUM( genrand_real( &rnd->mt) ) ;
}
而rb_define_method(rb_cRandom, "rand", random_rand, -1); 复制代码 这句就是在定义Random.rand了
random_rand长这样:
static VALUE
random_rand( int argc, VALUE *argv, VALUE obj)
{
VALUE v = rand_random( argc, argv, obj, get_rnd( obj) ) ;
check_random_number( v, argv) ;
return v;
}
static VALUE
rand_random( int argc, VALUE *argv, VALUE obj, rb_random_t *rnd)
{
VALUE vmax, v;
if ( rb_check_arity( argc, 0 , 1 ) == 0 ) {
return rb_float_new( random_real( obj, rnd, TRUE ) ) ;
}
vmax = argv[ 0 ] ;
if ( NIL_P( vmax) ) return Qnil;
if ( !RB_TYPE_P( vmax, T_FLOAT) ) {
v = rb_check_to_int( vmax) ;
if ( !NIL_P( v) ) return rand_int( obj, rnd, v, 1 ) ;
}
v = rb_check_to_float( vmax) ;
if ( !NIL_P( v) ) {
const double max = float_value( v) ;
if ( max < 0.0 ) {
return Qnil;
}
else {
double r = random_real( obj, rnd, TRUE ) ;
if ( max > 0.0 ) r *= max;
return rb_float_new( r) ;
}
}
return rand_range( obj, rnd, vmax) ;
}
static VALUE
random_rand( int argc, VALUE *argv, VALUE obj)
{
VALUE v = rand_random( argc, argv, obj, get_rnd( obj) ) ;
check_random_number( v, argv) ;
return v;
}
static VALUE
rand_random( int argc, VALUE *argv, VALUE obj, rb_random_t *rnd)
{
VALUE vmax, v;
if ( rb_check_arity( argc, 0 , 1 ) == 0 ) {
return rb_float_new( random_real( obj, rnd, TRUE ) ) ;
}
vmax = argv[ 0 ] ;
if ( NIL_P( vmax) ) return Qnil;
if ( !RB_TYPE_P( vmax, T_FLOAT) ) {
v = rb_check_to_int( vmax) ;
if ( !NIL_P( v) ) return rand_int( obj, rnd, v, 1 ) ;
}
v = rb_check_to_float( vmax) ;
if ( !NIL_P( v) ) {
const double max = float_value( v) ;
if ( max < 0.0 ) {
return Qnil;
}
else {
double r = random_real( obj, rnd, TRUE ) ;
if ( max > 0.0 ) r *= max;
return rb_float_new( r) ;
}
}
return rand_range( obj, rnd, vmax) ;
}
很明显可以看出 Kernel的起始值直接通过 default_rand 获得,而Random的则是调用 get_rnd。
评分
查看全部评分