mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00

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
42 lines
777 B
C
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);
|
|
}
|