Project

General

Profile

Feature #2561 ยป ruby-1.8.7-fixnum_gcd.patch

numeric.c patch. - kstephens (Kurt Stephens), 01/22/2010 05:58 AM

View differences:

numeric.c
3022 3022
    return Qtrue;
3023 3023
}
3024 3024

  
3025
static VALUE
3026
fix_gcd(int argc, VALUE *argv, VALUE self) {
3027
  if ( argc != 1 ) {
3028
    rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 1);
3029
  } else {
3030
    /* Handle Fixnum#gcd(Fixnum) here. 
3031
     * Note: Cannot handle values <= FIXNUM_MIN here due to overflow during negation.
3032
     */
3033
    long a, b;
3034

  
3035
    if ( FIXNUM_P(argv[0]) && (a = FIX2LONG(self)) > FIXNUM_MIN && (b = FIX2LONG(argv[0])) > FIXNUM_MIN ) {
3036
      long min = a < 0 ? - a : a;
3037
      long max = b < 0 ? - b : b;
3038
      while ( min > 0 ) {
3039
       long tmp = min;
3040
       min = max % min;
3041
       max = tmp;
3042
      }
3043
      return LONG2FIX(max);
3044
    } else {
3045
      /* Delegate to Integer#gcd. */
3046
      return rb_call_super(1, argv);
3047
    }
3048
  }
3049
}
3050

  
3025 3051
void
3026 3052
Init_Numeric()
3027 3053
{
......
3115 3141
    rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1);
3116 3142
    rb_define_method(rb_cFixnum, "quo", fix_quo, 1);
3117 3143
    rb_define_method(rb_cFixnum, "fdiv", fix_quo, 1);
3144
    rb_define_method(rb_cFixnum, "gcd", fix_gcd, -1);
3118 3145
    rb_define_method(rb_cFixnum, "**", fix_pow, 1);
3119 3146

  
3120 3147
    rb_define_method(rb_cFixnum, "abs", fix_abs, 0);