1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/ext/rational/rational.c
knu d2e30d50cf * ext/rational/rational.c: Added to provide a fast implementation
of Fixnum#gcd (and maybe some others in the future) in C.  The
  base code was submitted by Kurt Stephens. [Feature #2561]

* ext/rational/lib/rational.rb: Moved from lib/rational.rb.  Make
  overall code optimization; submitted by Kurt Stephens.
  [Feature #2561]

* test/rational/test_rational.rb, test/rational/test_rational2.rb:
  Add tests for Rational, ported from trunk.

* test/rational/test_fixnum_gcd.rb: Add a test for Integer#gcd.
  Case values are only provided for i386 and amd64 at the moment;
  submitted by Kurt Stephens. [Feature #2561]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@26581 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-02-05 14:11:08 +00:00

42 lines
777 B
C

#include "ruby.h"
/*
* call-seq:
* fixnum.gcd(fixnum) -> fixnum
*
* Fixnum-specific optimized version of Integer#gcd. Delegates to
* Integer#gcd as necessary.
*/
static VALUE
fix_gcd(self, other)
VALUE self, other;
{
long a, b, min, max;
/*
* Note: Cannot handle values <= FIXNUM_MIN here due to overflow during negation.
*/
if (!FIXNUM_P(other) ||
(a = FIX2LONG(self)) <= FIXNUM_MIN ||
(b = FIX2LONG(other)) <= FIXNUM_MIN ) {
/* Delegate to Integer#gcd */
return rb_call_super(1, &other);
}
min = a < 0 ? -a : a;
max = b < 0 ? -b : b;
while (min > 0) {
long tmp = min;
min = max % min;
max = tmp;
}
return LONG2FIX(max);
}
void
Init_rational()
{
rb_define_method(rb_cFixnum, "gcd", fix_gcd, 1);
}