mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	both complex and rational are now builtin classes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15783 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									2694b2f937
								
							
						
					
					
						commit
						6125552c27
					
				
					 16 changed files with 4952 additions and 1065 deletions
				
			
		
							
								
								
									
										40
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										40
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,43 @@
 | 
			
		|||
Sun Mar 16 08:51:41 2008  Tadayoshi Funaba  <tadf@dotrb.org>
 | 
			
		||||
 | 
			
		||||
	* include/ruby/intern.h: added some declarations.
 | 
			
		||||
 | 
			
		||||
	* include/ruby/ruby.h: ditto.
 | 
			
		||||
 | 
			
		||||
	* common.mk: added some entries.
 | 
			
		||||
 | 
			
		||||
	* configure.in: added a check for signbit.
 | 
			
		||||
 | 
			
		||||
	* lib/complex.rb: nearly all of core definitions have been removed.
 | 
			
		||||
 | 
			
		||||
	* lib/rational.rb: ditto.
 | 
			
		||||
 | 
			
		||||
	* lib/mathn.rb: some trivial adjustments.
 | 
			
		||||
 | 
			
		||||
	* complex.c: new.
 | 
			
		||||
 | 
			
		||||
	* rational.c: ditto.
 | 
			
		||||
 | 
			
		||||
	* numeric.c (flo_{quo,rdiv}, fix_fdiv): added.
 | 
			
		||||
 | 
			
		||||
	* numeric.c ({num,int}_{numerator,denominator}): ditto.
 | 
			
		||||
 | 
			
		||||
	* bignum.c (rb_big_fdiv): ditto.
 | 
			
		||||
 | 
			
		||||
	* numeric.c (fix_{quo,pow}): now may yield rational number.
 | 
			
		||||
 | 
			
		||||
	* bignum.c (rb_big_{quo,pow}): ditto.
 | 
			
		||||
 | 
			
		||||
	* numeric.c (rb_{int,flo}_induced_from): now can accept rational.
 | 
			
		||||
 | 
			
		||||
	* gc.c (gc_mark_children, obj_free): now detects complex and rational.
 | 
			
		||||
 | 
			
		||||
	* inits.c (rb_call_inits): now calls Init_{Complex,Rational}.
 | 
			
		||||
 | 
			
		||||
	* test/ruby/test_complex.rb: new.
 | 
			
		||||
 | 
			
		||||
	* test/ruby/test_rational.rb: ditto.
 | 
			
		||||
 | 
			
		||||
Sat Mar 15 17:48:48 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* encoding.c (rb_enc_associate_index): pass unnecessary enc_capable().
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										21
									
								
								bignum.c
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								bignum.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1901,6 +1901,12 @@ static VALUE big_shift(VALUE x, int n)
 | 
			
		|||
 | 
			
		||||
static VALUE
 | 
			
		||||
rb_big_quo(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    return rb_funcall(rb_rational_raw1(x), '/', 1, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
rb_big_fdiv(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    double dx = big2dbl(x);
 | 
			
		||||
    double dy;
 | 
			
		||||
| 
						 | 
				
			
			@ -1947,7 +1953,7 @@ rb_big_quo(VALUE x, VALUE y)
 | 
			
		|||
	break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
	return rb_num_coerce_bin(x, y, rb_intern("quo"));
 | 
			
		||||
	return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
 | 
			
		||||
    }
 | 
			
		||||
    return DOUBLE2NUM(dx / dy);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2025,13 +2031,19 @@ rb_big_pow(VALUE x, VALUE y)
 | 
			
		|||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_BIGNUM:
 | 
			
		||||
	if (rb_funcall(y, '<', 1, INT2FIX(0)))
 | 
			
		||||
	  return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
 | 
			
		||||
 | 
			
		||||
	rb_warn("in a**b, b may be too big");
 | 
			
		||||
	d = rb_big2dbl(y);
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_FIXNUM:
 | 
			
		||||
	yy = FIX2LONG(y);
 | 
			
		||||
	if (yy > 0) {
 | 
			
		||||
 | 
			
		||||
	if (yy < 0)
 | 
			
		||||
	  return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
 | 
			
		||||
	else {
 | 
			
		||||
	    VALUE z = 0;
 | 
			
		||||
	    SIGNED_VALUE mask;
 | 
			
		||||
	    const long BIGLEN_LIMIT = 1024*1024 / SIZEOF_BDIGITS;
 | 
			
		||||
| 
						 | 
				
			
			@ -2050,7 +2062,7 @@ rb_big_pow(VALUE x, VALUE y)
 | 
			
		|||
	    }
 | 
			
		||||
	    return bignorm(z);
 | 
			
		||||
	}
 | 
			
		||||
	d = (double)yy;
 | 
			
		||||
	/* NOTREACHED */
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
| 
						 | 
				
			
			@ -2590,7 +2602,8 @@ Init_Bignum(void)
 | 
			
		|||
    rb_define_method(rb_cBignum, "modulo", rb_big_modulo, 1);
 | 
			
		||||
    rb_define_method(rb_cBignum, "remainder", rb_big_remainder, 1);
 | 
			
		||||
    rb_define_method(rb_cBignum, "quo", rb_big_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cBignum, "fdiv", rb_big_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cBignum, "rdiv", rb_big_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cBignum, "fdiv", rb_big_fdiv, 1);
 | 
			
		||||
    rb_define_method(rb_cBignum, "**", rb_big_pow, 1);
 | 
			
		||||
    rb_define_method(rb_cBignum, "&", rb_big_and, 1);
 | 
			
		||||
    rb_define_method(rb_cBignum, "|", rb_big_or, 1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,7 @@ COMMONOBJS    = array.$(OBJEXT) \
 | 
			
		|||
		bignum.$(OBJEXT) \
 | 
			
		||||
		class.$(OBJEXT) \
 | 
			
		||||
		compar.$(OBJEXT) \
 | 
			
		||||
		complex.$(OBJEXT) \
 | 
			
		||||
		dir.$(OBJEXT) \
 | 
			
		||||
		enum.$(OBJEXT) \
 | 
			
		||||
		enumerator.$(OBJEXT) \
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +46,7 @@ COMMONOBJS    = array.$(OBJEXT) \
 | 
			
		|||
		prec.$(OBJEXT) \
 | 
			
		||||
		random.$(OBJEXT) \
 | 
			
		||||
		range.$(OBJEXT) \
 | 
			
		||||
		rational.$(OBJEXT) \
 | 
			
		||||
		re.$(OBJEXT) \
 | 
			
		||||
		regcomp.$(OBJEXT) \
 | 
			
		||||
		regenc.$(OBJEXT) \
 | 
			
		||||
| 
						 | 
				
			
			@ -424,6 +426,9 @@ class.$(OBJEXT): {$(VPATH)}class.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
 | 
			
		|||
compar.$(OBJEXT): {$(VPATH)}compar.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
 | 
			
		||||
  {$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
 | 
			
		||||
  {$(VPATH)}st.h
 | 
			
		||||
complex.$(OBJEXT): {$(VPATH)}complex.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
 | 
			
		||||
  {$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
 | 
			
		||||
  {$(VPATH)}st.h
 | 
			
		||||
dir.$(OBJEXT): {$(VPATH)}dir.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
 | 
			
		||||
  {$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
 | 
			
		||||
  {$(VPATH)}st.h {$(VPATH)}util.h
 | 
			
		||||
| 
						 | 
				
			
			@ -530,6 +535,9 @@ random.$(OBJEXT): {$(VPATH)}random.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
 | 
			
		|||
range.$(OBJEXT): {$(VPATH)}range.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
 | 
			
		||||
  {$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
 | 
			
		||||
  {$(VPATH)}st.h
 | 
			
		||||
rational.$(OBJEXT): {$(VPATH)}rational.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
 | 
			
		||||
  {$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
 | 
			
		||||
  {$(VPATH)}st.h
 | 
			
		||||
re.$(OBJEXT): {$(VPATH)}re.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
 | 
			
		||||
  {$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
 | 
			
		||||
  {$(VPATH)}st.h {$(VPATH)}re.h {$(VPATH)}regex.h {$(VPATH)}oniguruma.h \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -693,7 +693,7 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot fsync getcwd
 | 
			
		|||
	      getpgrp setpgrp getpgid setpgid initgroups getgroups setgroups\
 | 
			
		||||
	      getpriority getrlimit setrlimit sysconf group_member\
 | 
			
		||||
	      dlopen sigprocmask sigaction sigsetjmp _setjmp vsnprintf snprintf\
 | 
			
		||||
	      setsid telldir seekdir fchmod cosh sinh tanh log2 round\
 | 
			
		||||
	      setsid telldir seekdir fchmod cosh sinh tanh log2 round signbit\
 | 
			
		||||
	      setuid setgid daemon select_large_fdset setenv unsetenv\
 | 
			
		||||
	      mktime timegm clock_gettime gettimeofday)
 | 
			
		||||
AC_ARG_ENABLE(setreuid,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								gc.c
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								gc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -127,6 +127,8 @@ typedef struct RVALUE {
 | 
			
		|||
	struct RFile   file;
 | 
			
		||||
	struct RNode   node;
 | 
			
		||||
	struct RMatch  match;
 | 
			
		||||
	struct RRational rational;
 | 
			
		||||
	struct RComplex complex;
 | 
			
		||||
    } as;
 | 
			
		||||
#ifdef GC_DEBUG
 | 
			
		||||
    char *file;
 | 
			
		||||
| 
						 | 
				
			
			@ -1128,6 +1130,16 @@ gc_mark_children(VALUE ptr, int lev)
 | 
			
		|||
	}
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_RATIONAL:
 | 
			
		||||
	gc_mark(obj->as.rational.num, lev);
 | 
			
		||||
	gc_mark(obj->as.rational.den, lev);
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_COMPLEX:
 | 
			
		||||
	gc_mark(obj->as.complex.real, lev);
 | 
			
		||||
	gc_mark(obj->as.complex.image, lev);
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_STRUCT:
 | 
			
		||||
	{
 | 
			
		||||
	    long len = RSTRUCT_LEN(obj);
 | 
			
		||||
| 
						 | 
				
			
			@ -1369,6 +1381,9 @@ obj_free(VALUE obj)
 | 
			
		|||
	    rb_io_fptr_finalize(RANY(obj)->as.file.fptr);
 | 
			
		||||
	}
 | 
			
		||||
	break;
 | 
			
		||||
      case T_RATIONAL:
 | 
			
		||||
      case T_COMPLEX:
 | 
			
		||||
	break;
 | 
			
		||||
      case T_ICLASS:
 | 
			
		||||
	/* iClass shares table with the module */
 | 
			
		||||
	break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,6 +117,26 @@ VALUE rb_big_or(VALUE, VALUE);
 | 
			
		|||
VALUE rb_big_xor(VALUE, VALUE);
 | 
			
		||||
VALUE rb_big_lshift(VALUE, VALUE);
 | 
			
		||||
VALUE rb_big_rshift(VALUE, VALUE);
 | 
			
		||||
/* rational.c */
 | 
			
		||||
VALUE rb_rational_raw(VALUE, VALUE);
 | 
			
		||||
#define rb_rational_raw1(x) rb_rational_raw(x, INT2FIX(1))
 | 
			
		||||
#define rb_rational_raw2(x,y) rb_rational_raw(x, y)
 | 
			
		||||
VALUE rb_rational_new(VALUE, VALUE);
 | 
			
		||||
#define rb_rational_new1(x) rb_rational_new(x, INT2FIX(1))
 | 
			
		||||
#define rb_rational_new2(x,y) rb_rational_new(x, y)
 | 
			
		||||
VALUE rb_Rational(VALUE, VALUE);
 | 
			
		||||
#define rb_Rational1(x) rb_Rational(x, INT2FIX(1))
 | 
			
		||||
#define rb_Rational2(x,y) rb_Rational(x, y)
 | 
			
		||||
/* complex.c */
 | 
			
		||||
VALUE rb_complex_raw(VALUE, VALUE);
 | 
			
		||||
#define rb_complex_raw1(x) rb_complex_raw(x, INT2FIX(0))
 | 
			
		||||
#define rb_complex_raw2(x,y) rb_complex_raw(x, y)
 | 
			
		||||
VALUE rb_complex_new(VALUE, VALUE);
 | 
			
		||||
#define rb_complex_new1(x) rb_complex_new(x, INT2FIX(0))
 | 
			
		||||
#define rb_complex_new2(x,y) rb_complex_new(x, y)
 | 
			
		||||
VALUE rb_Complex(VALUE, VALUE);
 | 
			
		||||
#define rb_Complex1(x) rb_Complex(x, INT2FIX(0))
 | 
			
		||||
#define rb_Complex2(x,y) rb_Complex(x, y)
 | 
			
		||||
/* class.c */
 | 
			
		||||
VALUE rb_class_boot(VALUE);
 | 
			
		||||
VALUE rb_class_new(VALUE);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -273,6 +273,11 @@ enum ruby_value_type {
 | 
			
		|||
    RUBY_T_SYMBOL = 0x14,
 | 
			
		||||
#define T_SYMBOL RUBY_T_SYMBOL
 | 
			
		||||
 | 
			
		||||
    RUBY_T_RATIONAL = 0x15,
 | 
			
		||||
#define T_RATIONAL RUBY_T_RATIONAL
 | 
			
		||||
    RUBY_T_COMPLEX = 0x16,
 | 
			
		||||
#define T_COMPLEX RUBY_T_COMPLEX
 | 
			
		||||
 | 
			
		||||
    RUBY_T_VALUES = 0x1a,
 | 
			
		||||
#define T_VALUES RUBY_T_VALUES
 | 
			
		||||
    RUBY_T_BLOCK  = 0x1b,
 | 
			
		||||
| 
						 | 
				
			
			@ -522,6 +527,18 @@ struct RFile {
 | 
			
		|||
    struct rb_io_t *fptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct RRational {
 | 
			
		||||
    struct RBasic basic;
 | 
			
		||||
    VALUE num;
 | 
			
		||||
    VALUE den;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct RComplex {
 | 
			
		||||
    struct RBasic basic;
 | 
			
		||||
    VALUE real;
 | 
			
		||||
    VALUE image;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct RData {
 | 
			
		||||
    struct RBasic basic;
 | 
			
		||||
    void (*dmark)(void*);
 | 
			
		||||
| 
						 | 
				
			
			@ -622,6 +639,8 @@ struct RBignum {
 | 
			
		|||
#define RSTRUCT(obj) (R_CAST(RStruct)(obj))
 | 
			
		||||
#define RBIGNUM(obj) (R_CAST(RBignum)(obj))
 | 
			
		||||
#define RFILE(obj)   (R_CAST(RFile)(obj))
 | 
			
		||||
#define RRATIONAL(obj) (R_CAST(RRational)(obj))
 | 
			
		||||
#define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
 | 
			
		||||
#define RVALUES(obj) (R_CAST(RValues)(obj))
 | 
			
		||||
 | 
			
		||||
#define FL_SINGLETON FL_USER0
 | 
			
		||||
| 
						 | 
				
			
			@ -851,6 +870,8 @@ RUBY_EXTERN VALUE rb_cNilClass;
 | 
			
		|||
RUBY_EXTERN VALUE rb_cNumeric;
 | 
			
		||||
RUBY_EXTERN VALUE rb_cProc;
 | 
			
		||||
RUBY_EXTERN VALUE rb_cRange;
 | 
			
		||||
RUBY_EXTERN VALUE rb_cRational;
 | 
			
		||||
RUBY_EXTERN VALUE rb_cComplex;
 | 
			
		||||
RUBY_EXTERN VALUE rb_cRegexp;
 | 
			
		||||
RUBY_EXTERN VALUE rb_cStat;
 | 
			
		||||
RUBY_EXTERN VALUE rb_cString;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								inits.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								inits.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -15,6 +15,7 @@ void Init_Array(void);
 | 
			
		|||
void Init_Bignum(void);
 | 
			
		||||
void Init_Binding(void);
 | 
			
		||||
void Init_Comparable(void);
 | 
			
		||||
void Init_Complex(void);
 | 
			
		||||
void Init_transcode(void);
 | 
			
		||||
void Init_Dir(void);
 | 
			
		||||
void Init_Enumerable(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +40,7 @@ void Init_id(void);
 | 
			
		|||
void Init_process(void);
 | 
			
		||||
void Init_Random(void);
 | 
			
		||||
void Init_Range(void);
 | 
			
		||||
void Init_Rational(void);
 | 
			
		||||
void Init_Regexp(void);
 | 
			
		||||
void Init_signal(void);
 | 
			
		||||
void Init_String(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -96,5 +98,7 @@ rb_call_inits()
 | 
			
		|||
    Init_ISeq();
 | 
			
		||||
    Init_Thread();
 | 
			
		||||
    Init_Cont();
 | 
			
		||||
    Init_Rational();
 | 
			
		||||
    Init_Complex();
 | 
			
		||||
    Init_version();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										634
									
								
								lib/complex.rb
									
										
									
									
									
								
							
							
						
						
									
										634
									
								
								lib/complex.rb
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,473 +1,90 @@
 | 
			
		|||
#
 | 
			
		||||
#   complex.rb - 
 | 
			
		||||
#   	$Release Version: 0.5 $
 | 
			
		||||
#   	$Revision: 1.3 $
 | 
			
		||||
#   	by Keiju ISHITSUKA(SHL Japan Inc.)
 | 
			
		||||
#
 | 
			
		||||
# ----
 | 
			
		||||
#
 | 
			
		||||
# complex.rb implements the Complex class for complex numbers.  Additionally,
 | 
			
		||||
# some methods in other Numeric classes are redefined or added to allow greater
 | 
			
		||||
# interoperability with Complex numbers.
 | 
			
		||||
#
 | 
			
		||||
# Complex numbers can be created in the following manner:
 | 
			
		||||
# - <tt>Complex(a, b)</tt>
 | 
			
		||||
# - <tt>Complex.polar(radius, theta)</tt>
 | 
			
		||||
#   
 | 
			
		||||
# Additionally, note the following:
 | 
			
		||||
# - <tt>Complex::I</tt> (the mathematical constant <i>i</i>)
 | 
			
		||||
# - <tt>Numeric#im</tt> (e.g. <tt>5.im -> 0+5i</tt>)
 | 
			
		||||
#
 | 
			
		||||
# The following +Math+ module methods are redefined to handle Complex arguments.
 | 
			
		||||
# They will work as normal with non-Complex arguments.
 | 
			
		||||
#    sqrt exp cos sin tan log log10
 | 
			
		||||
#    cosh sinh tanh acos asin atan atan2 acosh asinh atanh
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Numeric is a built-in class on which Fixnum, Bignum, etc., are based.  Here
 | 
			
		||||
# some methods are added so that all number types can be treated to some extent
 | 
			
		||||
# as Complex numbers.
 | 
			
		||||
#
 | 
			
		||||
class Numeric
 | 
			
		||||
  #
 | 
			
		||||
  # Returns a Complex number <tt>(0,<i>self</i>)</tt>.
 | 
			
		||||
  #
 | 
			
		||||
  def im
 | 
			
		||||
    Complex(0, self)
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # The real part of a complex number, i.e. <i>self</i>.
 | 
			
		||||
  #
 | 
			
		||||
  def real
 | 
			
		||||
    self
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # The imaginary part of a complex number, i.e. 0.
 | 
			
		||||
  #
 | 
			
		||||
  def image
 | 
			
		||||
    0
 | 
			
		||||
  end
 | 
			
		||||
  alias imag image
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # See Complex#arg.
 | 
			
		||||
  #
 | 
			
		||||
  def arg
 | 
			
		||||
    if self >= 0
 | 
			
		||||
      return 0
 | 
			
		||||
    else
 | 
			
		||||
      return Math::PI
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  alias angle arg
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # See Complex#polar.
 | 
			
		||||
  #
 | 
			
		||||
  def polar
 | 
			
		||||
    return abs, arg
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # See Complex#conjugate (short answer: returns <i>self</i>).
 | 
			
		||||
  #
 | 
			
		||||
  def conjugate
 | 
			
		||||
    self
 | 
			
		||||
  end
 | 
			
		||||
  alias conj conjugate
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Creates a Complex number.  +a+ and +b+ should be Numeric.  The result will be
 | 
			
		||||
# <tt>a+bi</tt>.
 | 
			
		||||
#
 | 
			
		||||
def Complex(a, b = 0)
 | 
			
		||||
  if b == 0 and (a.kind_of?(Complex) or defined? Complex::Unify)
 | 
			
		||||
    a
 | 
			
		||||
  elsif a.scalar? and b.scalar?
 | 
			
		||||
    # Don't delete for -0.0
 | 
			
		||||
    Complex.new(a, b)
 | 
			
		||||
  else
 | 
			
		||||
    Complex.new( a.real-b.imag, a.imag+b.real )
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# The complex number class.  See complex.rb for an overview.
 | 
			
		||||
#
 | 
			
		||||
class Complex < Numeric
 | 
			
		||||
  @RCS_ID='-$Id: complex.rb,v 1.3 1998/07/08 10:05:28 keiju Exp keiju $-'
 | 
			
		||||
 | 
			
		||||
  undef step
 | 
			
		||||
  undef <, <=, <=>, >, >=
 | 
			
		||||
  undef between?
 | 
			
		||||
  undef div, divmod, modulo
 | 
			
		||||
  undef floor, truncate, ceil, round
 | 
			
		||||
 | 
			
		||||
  def scalar?
 | 
			
		||||
    false
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def Complex.generic?(other) # :nodoc:
 | 
			
		||||
    other.kind_of?(Integer) or
 | 
			
		||||
    other.kind_of?(Float) or
 | 
			
		||||
    (defined?(Rational) and other.kind_of?(Rational))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Creates a +Complex+ number in terms of +r+ (radius) and +theta+ (angle).
 | 
			
		||||
  #
 | 
			
		||||
  def Complex.polar(r, theta)
 | 
			
		||||
    Complex(r*Math.cos(theta), r*Math.sin(theta))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Creates a +Complex+ number <tt>a</tt>+<tt>b</tt><i>i</i>.
 | 
			
		||||
  #
 | 
			
		||||
  def Complex.new!(a, b=0)
 | 
			
		||||
    new(a,b)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def initialize(a, b)
 | 
			
		||||
    raise TypeError, "non numeric 1st arg `#{a.inspect}'" if !a.kind_of? Numeric
 | 
			
		||||
    raise TypeError, "`#{a.inspect}' for 1st arg" if a.kind_of? Complex
 | 
			
		||||
    raise TypeError, "non numeric 2nd arg `#{b.inspect}'" if !b.kind_of? Numeric
 | 
			
		||||
    raise TypeError, "`#{b.inspect}' for 2nd arg" if b.kind_of? Complex
 | 
			
		||||
    @real = a
 | 
			
		||||
    @image = b
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Addition with real or complex number.
 | 
			
		||||
  #
 | 
			
		||||
  def + (other)
 | 
			
		||||
    if other.kind_of?(Complex)
 | 
			
		||||
      re = @real + other.real
 | 
			
		||||
      im = @image + other.image
 | 
			
		||||
      Complex(re, im)
 | 
			
		||||
    elsif Complex.generic?(other)
 | 
			
		||||
      Complex(@real + other, @image)
 | 
			
		||||
    else
 | 
			
		||||
      x , y = other.coerce(self)
 | 
			
		||||
      x + y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Subtraction with real or complex number.
 | 
			
		||||
  #
 | 
			
		||||
  def - (other)
 | 
			
		||||
    if other.kind_of?(Complex)
 | 
			
		||||
      re = @real - other.real
 | 
			
		||||
      im = @image - other.image
 | 
			
		||||
      Complex(re, im)
 | 
			
		||||
    elsif Complex.generic?(other)
 | 
			
		||||
      Complex(@real - other, @image)
 | 
			
		||||
    else
 | 
			
		||||
      x , y = other.coerce(self)
 | 
			
		||||
      x - y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Multiplication with real or complex number.
 | 
			
		||||
  #
 | 
			
		||||
  def * (other)
 | 
			
		||||
    if other.kind_of?(Complex)
 | 
			
		||||
      re = @real*other.real - @image*other.image
 | 
			
		||||
      im = @real*other.image + @image*other.real
 | 
			
		||||
      Complex(re, im)
 | 
			
		||||
    elsif Complex.generic?(other)
 | 
			
		||||
      Complex(@real * other, @image * other)
 | 
			
		||||
    else
 | 
			
		||||
      x , y = other.coerce(self)
 | 
			
		||||
      x * y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Division by real or complex number.
 | 
			
		||||
  #
 | 
			
		||||
  def / (other)
 | 
			
		||||
    if other.kind_of?(Complex)
 | 
			
		||||
      self*other.conjugate/other.abs2
 | 
			
		||||
    elsif Complex.generic?(other)
 | 
			
		||||
      Complex(@real/other, @image/other)
 | 
			
		||||
    else
 | 
			
		||||
      x, y = other.coerce(self)
 | 
			
		||||
      x/y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def quo(other)
 | 
			
		||||
    Complex(@real.quo(1), @image.quo(1)) / other
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Raise this complex number to the given (real or complex) power.
 | 
			
		||||
  #
 | 
			
		||||
  def ** (other)
 | 
			
		||||
    if other == 0
 | 
			
		||||
      return Complex(1)
 | 
			
		||||
    end
 | 
			
		||||
    if other.kind_of?(Complex)
 | 
			
		||||
      r, theta = polar
 | 
			
		||||
      ore = other.real
 | 
			
		||||
      oim = other.image
 | 
			
		||||
      nr = Math.exp!(ore*Math.log!(r) - oim * theta)
 | 
			
		||||
      ntheta = theta*ore + oim*Math.log!(r)
 | 
			
		||||
      Complex.polar(nr, ntheta)
 | 
			
		||||
    elsif other.kind_of?(Integer)
 | 
			
		||||
      if other > 0
 | 
			
		||||
	x = self
 | 
			
		||||
	z = x
 | 
			
		||||
	n = other - 1
 | 
			
		||||
	while n != 0
 | 
			
		||||
	  while (div, mod = n.divmod(2)
 | 
			
		||||
		 mod == 0)
 | 
			
		||||
	    x = Complex(x.real*x.real - x.image*x.image, 2*x.real*x.image)
 | 
			
		||||
	    n = div
 | 
			
		||||
	  end
 | 
			
		||||
	  z *= x
 | 
			
		||||
	  n -= 1
 | 
			
		||||
	end
 | 
			
		||||
	z
 | 
			
		||||
      else
 | 
			
		||||
	if defined? Rational
 | 
			
		||||
	  (Rational(1) / self) ** -other
 | 
			
		||||
	else
 | 
			
		||||
	  self ** Float(other)
 | 
			
		||||
	end
 | 
			
		||||
      end
 | 
			
		||||
    elsif Complex.generic?(other)
 | 
			
		||||
      r, theta = polar
 | 
			
		||||
      Complex.polar(r**other, theta*other)
 | 
			
		||||
    else
 | 
			
		||||
      x, y = other.coerce(self)
 | 
			
		||||
      x**y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Remainder after division by a real or complex number.
 | 
			
		||||
  #
 | 
			
		||||
 | 
			
		||||
=begin
 | 
			
		||||
  def % (other)
 | 
			
		||||
    if other.kind_of?(Complex)
 | 
			
		||||
      Complex(@real % other.real, @image % other.image)
 | 
			
		||||
    elsif Complex.generic?(other)
 | 
			
		||||
      Complex(@real % other, @image % other)
 | 
			
		||||
    else
 | 
			
		||||
      x , y = other.coerce(self)
 | 
			
		||||
      x % y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
=end
 | 
			
		||||
 | 
			
		||||
#--
 | 
			
		||||
#    def divmod(other)
 | 
			
		||||
#      if other.kind_of?(Complex)
 | 
			
		||||
#        rdiv, rmod = @real.divmod(other.real)
 | 
			
		||||
#        idiv, imod = @image.divmod(other.image)
 | 
			
		||||
#        return Complex(rdiv, idiv), Complex(rmod, rmod)
 | 
			
		||||
#      elsif Complex.generic?(other)
 | 
			
		||||
#        Complex(@real.divmod(other), @image.divmod(other))
 | 
			
		||||
#      else
 | 
			
		||||
#        x , y = other.coerce(self)
 | 
			
		||||
#        x.divmod(y)
 | 
			
		||||
#      end
 | 
			
		||||
#    end
 | 
			
		||||
#++
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Absolute value (aka modulus): distance from the zero point on the complex
 | 
			
		||||
  # plane.
 | 
			
		||||
  #
 | 
			
		||||
  def abs
 | 
			
		||||
    Math.hypot(@real, @image)
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Square of the absolute value.
 | 
			
		||||
  #
 | 
			
		||||
  def abs2
 | 
			
		||||
    @real*@real + @image*@image
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Argument (angle from (1,0) on the complex plane).
 | 
			
		||||
  #
 | 
			
		||||
  def arg
 | 
			
		||||
    Math.atan2!(@image, @real)
 | 
			
		||||
  end
 | 
			
		||||
  alias angle arg
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the absolute value _and_ the argument.
 | 
			
		||||
  #
 | 
			
		||||
  def polar
 | 
			
		||||
    return abs, arg
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Complex conjugate (<tt>z + z.conjugate = 2 * z.real</tt>).
 | 
			
		||||
  #
 | 
			
		||||
  def conjugate
 | 
			
		||||
    Complex(@real, -@image)
 | 
			
		||||
  end
 | 
			
		||||
  alias conj conjugate
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Test for numerical equality (<tt>a == a + 0<i>i</i></tt>).
 | 
			
		||||
  #
 | 
			
		||||
  def == (other)
 | 
			
		||||
    if other.kind_of?(Complex)
 | 
			
		||||
      @real == other.real and @image == other.image
 | 
			
		||||
    elsif Complex.generic?(other)
 | 
			
		||||
      @real == other and @image == 0
 | 
			
		||||
    else
 | 
			
		||||
      other == self
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Attempts to coerce +other+ to a Complex number.
 | 
			
		||||
  #
 | 
			
		||||
  def coerce(other)
 | 
			
		||||
    if Complex.generic?(other)
 | 
			
		||||
      return Complex.new!(other), self
 | 
			
		||||
    else
 | 
			
		||||
      super
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # FIXME
 | 
			
		||||
  #
 | 
			
		||||
  def denominator
 | 
			
		||||
    @real.denominator.lcm(@image.denominator)
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # FIXME
 | 
			
		||||
  #
 | 
			
		||||
  def numerator
 | 
			
		||||
    cd = denominator
 | 
			
		||||
    Complex(@real.numerator*(cd/@real.denominator),
 | 
			
		||||
	    @image.numerator*(cd/@image.denominator))
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Standard string representation of the complex number.
 | 
			
		||||
  #
 | 
			
		||||
  def to_s
 | 
			
		||||
    if @real != 0
 | 
			
		||||
      if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
 | 
			
		||||
	if @image >= 0
 | 
			
		||||
	  @real.to_s+"+("+@image.to_s+")i"
 | 
			
		||||
	else
 | 
			
		||||
	  @real.to_s+"-("+(-@image).to_s+")i"
 | 
			
		||||
	end
 | 
			
		||||
      else
 | 
			
		||||
	if @image >= 0
 | 
			
		||||
	  @real.to_s+"+"+@image.to_s+"i"
 | 
			
		||||
	else
 | 
			
		||||
	  @real.to_s+"-"+(-@image).to_s+"i"
 | 
			
		||||
	end
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
 | 
			
		||||
	"("+@image.to_s+")i"
 | 
			
		||||
      else
 | 
			
		||||
	@image.to_s+"i"
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Returns a hash code for the complex number.
 | 
			
		||||
  #
 | 
			
		||||
  def hash
 | 
			
		||||
    @real.hash ^ @image.hash
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # Returns "<tt>Complex(<i>real</i>, <i>image</i>)</tt>".
 | 
			
		||||
  #
 | 
			
		||||
  def inspect
 | 
			
		||||
    sprintf("Complex(%s, %s)", @real.inspect, @image.inspect)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  #
 | 
			
		||||
  # +I+ is the imaginary number.  It exists at point (0,1) on the complex plane.
 | 
			
		||||
  #
 | 
			
		||||
  I = Complex(0,1)
 | 
			
		||||
  
 | 
			
		||||
  # The real part of a complex number.
 | 
			
		||||
  attr_reader :real
 | 
			
		||||
 | 
			
		||||
  # The imaginary part of a complex number.
 | 
			
		||||
  attr_reader :image
 | 
			
		||||
  alias imag image
 | 
			
		||||
  
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class Integer
 | 
			
		||||
 | 
			
		||||
  unless defined?(1.numerator)
 | 
			
		||||
    def numerator() self end
 | 
			
		||||
    def denominator() 1 end
 | 
			
		||||
 | 
			
		||||
    def gcd(other)
 | 
			
		||||
      min = self.abs
 | 
			
		||||
      max = other.abs
 | 
			
		||||
      while min > 0
 | 
			
		||||
        tmp = min
 | 
			
		||||
        min = max % min
 | 
			
		||||
        max = tmp
 | 
			
		||||
      end
 | 
			
		||||
      max
 | 
			
		||||
  def gcd(other)
 | 
			
		||||
    min = self.abs
 | 
			
		||||
    max = other.abs
 | 
			
		||||
    while min > 0
 | 
			
		||||
      tmp = min
 | 
			
		||||
      min = max % min
 | 
			
		||||
      max = tmp
 | 
			
		||||
    end
 | 
			
		||||
    max
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
    def lcm(other)
 | 
			
		||||
      if self.zero? or other.zero?
 | 
			
		||||
        0
 | 
			
		||||
      else
 | 
			
		||||
        (self.div(self.gcd(other)) * other).abs
 | 
			
		||||
      end
 | 
			
		||||
  def lcm(other)
 | 
			
		||||
    if self.zero? or other.zero?
 | 
			
		||||
      0
 | 
			
		||||
    else
 | 
			
		||||
      (self.div(self.gcd(other)) * other).abs
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def gcdlcm(other)
 | 
			
		||||
    gcd = self.gcd(other)
 | 
			
		||||
    if self.zero? or other.zero?
 | 
			
		||||
      [gcd, 0]
 | 
			
		||||
    else
 | 
			
		||||
      [gcd, (self.div(gcd) * other).abs]
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
module Math
 | 
			
		||||
  alias sqrt! sqrt
 | 
			
		||||
 | 
			
		||||
  alias exp! exp
 | 
			
		||||
  alias log! log
 | 
			
		||||
  alias log10! log10
 | 
			
		||||
  alias cos! cos
 | 
			
		||||
  alias sqrt! sqrt
 | 
			
		||||
 | 
			
		||||
  alias sin! sin
 | 
			
		||||
  alias cos! cos
 | 
			
		||||
  alias tan! tan
 | 
			
		||||
  alias cosh! cosh
 | 
			
		||||
 | 
			
		||||
  alias sinh! sinh
 | 
			
		||||
  alias cosh! cosh
 | 
			
		||||
  alias tanh! tanh
 | 
			
		||||
  alias acos! acos
 | 
			
		||||
 | 
			
		||||
  alias asin! asin
 | 
			
		||||
  alias acos! acos
 | 
			
		||||
  alias atan! atan
 | 
			
		||||
  alias atan2! atan2
 | 
			
		||||
  alias acosh! acosh
 | 
			
		||||
 | 
			
		||||
  alias asinh! asinh
 | 
			
		||||
  alias acosh! acosh
 | 
			
		||||
  alias atanh! atanh
 | 
			
		||||
 | 
			
		||||
  # Redefined to handle a Complex argument.
 | 
			
		||||
  def exp(z)
 | 
			
		||||
    if Complex.generic?(z)
 | 
			
		||||
      exp!(z)
 | 
			
		||||
    else
 | 
			
		||||
      Complex(exp!(z.real) * cos!(z.image),
 | 
			
		||||
	      exp!(z.real) * sin!(z.image))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def log(*args)
 | 
			
		||||
    z, b = args
 | 
			
		||||
    if Complex.generic?(z) and z >= 0 and (b.nil? or b >= 0)
 | 
			
		||||
      log!(*args)
 | 
			
		||||
    else
 | 
			
		||||
      r, theta = z.polar
 | 
			
		||||
      a = Complex(log!(r.abs), theta)
 | 
			
		||||
      if b
 | 
			
		||||
	a /= log(b)
 | 
			
		||||
      end
 | 
			
		||||
      a
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def log10(z)
 | 
			
		||||
    if Complex.generic?(z)
 | 
			
		||||
      log10!(z)
 | 
			
		||||
    else
 | 
			
		||||
      log(z) / log!(10)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def sqrt(z)
 | 
			
		||||
    if Complex.generic?(z)
 | 
			
		||||
      if z >= 0
 | 
			
		||||
| 
						 | 
				
			
			@ -481,41 +98,29 @@ module Math
 | 
			
		|||
      else
 | 
			
		||||
	r = z.abs
 | 
			
		||||
	x = z.real
 | 
			
		||||
	Complex( sqrt!((r+x)/2), sqrt!((r-x)/2) )
 | 
			
		||||
	Complex(sqrt!((r + x) / 2), sqrt!((r - x) / 2))
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Redefined to handle a Complex argument.
 | 
			
		||||
  def exp(z)
 | 
			
		||||
    if Complex.generic?(z)
 | 
			
		||||
      exp!(z)
 | 
			
		||||
    else
 | 
			
		||||
      Complex(exp!(z.real) * cos!(z.image), exp!(z.real) * sin!(z.image))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  # Redefined to handle a Complex argument.
 | 
			
		||||
  def cos(z)
 | 
			
		||||
    if Complex.generic?(z)
 | 
			
		||||
      cos!(z)
 | 
			
		||||
    else
 | 
			
		||||
      Complex(cos!(z.real)*cosh!(z.image),
 | 
			
		||||
	      -sin!(z.real)*sinh!(z.image))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
    
 | 
			
		||||
  # Redefined to handle a Complex argument.
 | 
			
		||||
  def sin(z)
 | 
			
		||||
    if Complex.generic?(z)
 | 
			
		||||
      sin!(z)
 | 
			
		||||
    else
 | 
			
		||||
      Complex(sin!(z.real)*cosh!(z.image),
 | 
			
		||||
	      cos!(z.real)*sinh!(z.image))
 | 
			
		||||
      Complex(sin!(z.real) * cosh!(z.image),
 | 
			
		||||
	      cos!(z.real) * sinh!(z.image))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def cos(z)
 | 
			
		||||
    if Complex.generic?(z)
 | 
			
		||||
      cos!(z)
 | 
			
		||||
    else
 | 
			
		||||
      Complex(cos!(z.real) * cosh!(z.image),
 | 
			
		||||
	      -sin!(z.real) * sinh!(z.image))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Redefined to handle a Complex argument.
 | 
			
		||||
  def tan(z)
 | 
			
		||||
    if Complex.generic?(z)
 | 
			
		||||
      tan!(z)
 | 
			
		||||
| 
						 | 
				
			
			@ -528,7 +133,8 @@ module Math
 | 
			
		|||
    if Complex.generic?(z)
 | 
			
		||||
      sinh!(z)
 | 
			
		||||
    else
 | 
			
		||||
      Complex( sinh!(z.real)*cos!(z.image), cosh!(z.real)*sin!(z.image) )
 | 
			
		||||
      Complex(sinh!(z.real) * cos!(z.image),
 | 
			
		||||
	      cosh!(z.real) * sin!(z.image))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -536,7 +142,8 @@ module Math
 | 
			
		|||
    if Complex.generic?(z)
 | 
			
		||||
      cosh!(z)
 | 
			
		||||
    else
 | 
			
		||||
      Complex( cosh!(z.real)*cos!(z.image), sinh!(z.real)*sin!(z.image) )
 | 
			
		||||
      Complex(cosh!(z.real) * cos!(z.image),
 | 
			
		||||
	      sinh!(z.real) * sin!(z.image))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -544,34 +151,7 @@ module Math
 | 
			
		|||
    if Complex.generic?(z)
 | 
			
		||||
      tanh!(z)
 | 
			
		||||
    else
 | 
			
		||||
      sinh(z)/cosh(z)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  # Redefined to handle a Complex argument.
 | 
			
		||||
  def log(z)
 | 
			
		||||
    if Complex.generic?(z) and z >= 0
 | 
			
		||||
      log!(z)
 | 
			
		||||
    else
 | 
			
		||||
      r, theta = z.polar
 | 
			
		||||
      Complex(log!(r.abs), theta)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  # Redefined to handle a Complex argument.
 | 
			
		||||
  def log10(z)
 | 
			
		||||
    if Complex.generic?(z)
 | 
			
		||||
      log10!(z)
 | 
			
		||||
    else
 | 
			
		||||
      log(z)/log!(10)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def acos(z)
 | 
			
		||||
    if Complex.generic?(z) and z >= -1 and z <= 1
 | 
			
		||||
      acos!(z)
 | 
			
		||||
    else
 | 
			
		||||
      -1.0.im * log( z + 1.0.im * sqrt(1.0-z*z) )
 | 
			
		||||
      sinh(z) / cosh(z)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -579,7 +159,15 @@ module Math
 | 
			
		|||
    if Complex.generic?(z) and z >= -1 and z <= 1
 | 
			
		||||
      asin!(z)
 | 
			
		||||
    else
 | 
			
		||||
      -1.0.im * log( 1.0.im * z + sqrt(1.0-z*z) )
 | 
			
		||||
      -1.0.im * log(1.0.im * z + sqrt(1.0 - z * z))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def acos(z)
 | 
			
		||||
    if Complex.generic?(z) and z >= -1 and z <= 1
 | 
			
		||||
      acos!(z)
 | 
			
		||||
    else
 | 
			
		||||
      -1.0.im * log(z + 1.0.im * sqrt(1.0 - z * z))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -587,7 +175,7 @@ module Math
 | 
			
		|||
    if Complex.generic?(z)
 | 
			
		||||
      atan!(z)
 | 
			
		||||
    else
 | 
			
		||||
      1.0.im * log( (1.0.im+z) / (1.0.im-z) ) / 2.0
 | 
			
		||||
      1.0.im * log((1.0.im + z) / (1.0.im - z)) / 2.0
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -595,7 +183,7 @@ module Math
 | 
			
		|||
    if Complex.generic?(y) and Complex.generic?(x)
 | 
			
		||||
      atan2!(y,x)
 | 
			
		||||
    else
 | 
			
		||||
      -1.0.im * log( (x+1.0.im*y) / sqrt(x*x+y*y) )
 | 
			
		||||
      -1.0.im * log((x + 1.0.im * y) / sqrt(x * x + y * y))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -603,7 +191,7 @@ module Math
 | 
			
		|||
    if Complex.generic?(z) and z >= 1
 | 
			
		||||
      acosh!(z)
 | 
			
		||||
    else
 | 
			
		||||
      log( z + sqrt(z*z-1.0) )
 | 
			
		||||
      log(z + sqrt(z * z - 1.0))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -611,7 +199,7 @@ module Math
 | 
			
		|||
    if Complex.generic?(z)
 | 
			
		||||
      asinh!(z)
 | 
			
		||||
    else
 | 
			
		||||
      log( z + sqrt(1.0+z*z) )
 | 
			
		||||
      log(z + sqrt(1.0 + z * z))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -619,49 +207,47 @@ module Math
 | 
			
		|||
    if Complex.generic?(z) and z >= -1 and z <= 1
 | 
			
		||||
      atanh!(z)
 | 
			
		||||
    else
 | 
			
		||||
      log( (1.0+z) / (1.0-z) ) / 2.0
 | 
			
		||||
      log((1.0 + z) / (1.0 - z)) / 2.0
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  module_function :sqrt!
 | 
			
		||||
  module_function :sqrt
 | 
			
		||||
  module_function :exp!
 | 
			
		||||
  module_function :exp
 | 
			
		||||
  module_function :log!
 | 
			
		||||
  module_function :log
 | 
			
		||||
  module_function :log10!
 | 
			
		||||
  module_function :log10
 | 
			
		||||
  module_function :cosh!
 | 
			
		||||
  module_function :cosh
 | 
			
		||||
  module_function :cos!
 | 
			
		||||
  module_function :cos
 | 
			
		||||
  module_function :sinh!
 | 
			
		||||
  module_function :sinh
 | 
			
		||||
  module_function :sqrt!
 | 
			
		||||
  module_function :sqrt
 | 
			
		||||
 | 
			
		||||
  module_function :sin!
 | 
			
		||||
  module_function :sin
 | 
			
		||||
  module_function :cos!
 | 
			
		||||
  module_function :cos
 | 
			
		||||
  module_function :tan!
 | 
			
		||||
  module_function :tan
 | 
			
		||||
 | 
			
		||||
  module_function :sinh!
 | 
			
		||||
  module_function :sinh
 | 
			
		||||
  module_function :cosh!
 | 
			
		||||
  module_function :cosh
 | 
			
		||||
  module_function :tanh!
 | 
			
		||||
  module_function :tanh
 | 
			
		||||
  module_function :acos!
 | 
			
		||||
  module_function :acos
 | 
			
		||||
 | 
			
		||||
  module_function :asin!
 | 
			
		||||
  module_function :asin
 | 
			
		||||
  module_function :acos!
 | 
			
		||||
  module_function :acos
 | 
			
		||||
  module_function :atan!
 | 
			
		||||
  module_function :atan
 | 
			
		||||
  module_function :atan2!
 | 
			
		||||
  module_function :atan2
 | 
			
		||||
  module_function :acosh!
 | 
			
		||||
  module_function :acosh
 | 
			
		||||
 | 
			
		||||
  module_function :asinh!
 | 
			
		||||
  module_function :asinh
 | 
			
		||||
  module_function :acosh!
 | 
			
		||||
  module_function :acosh
 | 
			
		||||
  module_function :atanh!
 | 
			
		||||
  module_function :atanh
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# Documentation comments:
 | 
			
		||||
#  - source: original (researched from pickaxe)
 | 
			
		||||
#  - a couple of fixme's
 | 
			
		||||
#  - RDoc output for Bignum etc. is a bit short, with nothing but an
 | 
			
		||||
#    (undocumented) alias.  No big deal.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ class Rational
 | 
			
		|||
    if other.kind_of?(Rational)
 | 
			
		||||
      other2 = other
 | 
			
		||||
      if self < 0
 | 
			
		||||
	return Complex.new!(self, 0) ** other
 | 
			
		||||
	return Complex.__send__(:new!, self, 0) ** other
 | 
			
		||||
      elsif other == 0
 | 
			
		||||
	return Rational(1,1)
 | 
			
		||||
      elsif self == 0
 | 
			
		||||
| 
						 | 
				
			
			@ -175,7 +175,7 @@ class Rational
 | 
			
		|||
	num = 1
 | 
			
		||||
	den = 1
 | 
			
		||||
      end
 | 
			
		||||
      Rational.new!(num, den)
 | 
			
		||||
      Rational(num, den)
 | 
			
		||||
    elsif other.kind_of?(Float)
 | 
			
		||||
      Float(self) ** other
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			@ -187,7 +187,7 @@ class Rational
 | 
			
		|||
  def power2(other)
 | 
			
		||||
    if other.kind_of?(Rational)
 | 
			
		||||
      if self < 0
 | 
			
		||||
	return Complex(self, 0) ** other
 | 
			
		||||
	return Complex.__send__(:new!, self, 0) ** other
 | 
			
		||||
      elsif other == 0
 | 
			
		||||
	return Rational(1,1)
 | 
			
		||||
      elsif self == 0
 | 
			
		||||
| 
						 | 
				
			
			@ -219,7 +219,7 @@ class Rational
 | 
			
		|||
	num = 1
 | 
			
		||||
	den = 1
 | 
			
		||||
      end
 | 
			
		||||
      Rational.new!(num, den)
 | 
			
		||||
      Rational(num, den)
 | 
			
		||||
    elsif other.kind_of?(Float)
 | 
			
		||||
      Float(self) ** other
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			@ -306,4 +306,3 @@ end
 | 
			
		|||
class Complex
 | 
			
		||||
  Unify = true
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										530
									
								
								lib/rational.rb
									
										
									
									
									
								
							
							
						
						
									
										530
									
								
								lib/rational.rb
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,469 +1,23 @@
 | 
			
		|||
#
 | 
			
		||||
#   rational.rb -
 | 
			
		||||
#       $Release Version: 0.5 $
 | 
			
		||||
#       $Revision: 1.7 $
 | 
			
		||||
#       by Keiju ISHITSUKA(SHL Japan Inc.)
 | 
			
		||||
#
 | 
			
		||||
# Documentation by Kevin Jackson and Gavin Sinclair.
 | 
			
		||||
# 
 | 
			
		||||
# When you <tt>require 'rational'</tt>, all interactions between numbers
 | 
			
		||||
# potentially return a rational result.  For example:
 | 
			
		||||
#
 | 
			
		||||
#   1.quo(2)              # -> 0.5
 | 
			
		||||
#   require 'rational'
 | 
			
		||||
#   1.quo(2)              # -> Rational(1,2)
 | 
			
		||||
# 
 | 
			
		||||
# See Rational for full documentation.
 | 
			
		||||
#
 | 
			
		||||
class Fixnum
 | 
			
		||||
 | 
			
		||||
  alias quof fdiv
 | 
			
		||||
 | 
			
		||||
  alias power! **
 | 
			
		||||
  alias rpower **
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Creates a Rational number (i.e. a fraction).  +a+ and +b+ should be Integers:
 | 
			
		||||
# 
 | 
			
		||||
#   Rational(1,3)           # -> 1/3
 | 
			
		||||
#
 | 
			
		||||
# Note: trying to construct a Rational with floating point or real values
 | 
			
		||||
# produces errors:
 | 
			
		||||
#
 | 
			
		||||
#   Rational(1.1, 2.3)      # -> NoMethodError
 | 
			
		||||
#
 | 
			
		||||
def Rational(a, b = 1)
 | 
			
		||||
  if a.kind_of?(Rational) && b == 1
 | 
			
		||||
    a
 | 
			
		||||
  else
 | 
			
		||||
    Rational.reduce(a, b)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Rational implements a rational class for numbers.
 | 
			
		||||
#
 | 
			
		||||
# <em>A rational number is a number that can be expressed as a fraction p/q
 | 
			
		||||
# where p and q are integers and q != 0.  A rational number p/q is said to have
 | 
			
		||||
# numerator p and denominator q.  Numbers that are not rational are called
 | 
			
		||||
# irrational numbers.</em> (http://mathworld.wolfram.com/RationalNumber.html)
 | 
			
		||||
#
 | 
			
		||||
# To create a Rational Number:
 | 
			
		||||
#   Rational(a,b)             # -> a/b
 | 
			
		||||
#   Rational.new!(a,b)        # -> a/b
 | 
			
		||||
#
 | 
			
		||||
# Examples:
 | 
			
		||||
#   Rational(5,6)             # -> 5/6
 | 
			
		||||
#   Rational(5)               # -> 5/1
 | 
			
		||||
# 
 | 
			
		||||
# Rational numbers are reduced to their lowest terms:
 | 
			
		||||
#   Rational(6,10)            # -> 3/5
 | 
			
		||||
#
 | 
			
		||||
# But not if you use the unusual method "new!":
 | 
			
		||||
#   Rational.new!(6,10)       # -> 6/10
 | 
			
		||||
#
 | 
			
		||||
# Division by zero is obviously not allowed:
 | 
			
		||||
#   Rational(3,0)             # -> ZeroDivisionError
 | 
			
		||||
#
 | 
			
		||||
class Rational < Numeric
 | 
			
		||||
  @RCS_ID='-$Id: rational.rb,v 1.7 1999/08/24 12:49:28 keiju Exp keiju $-'
 | 
			
		||||
class Bignum
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Reduces the given numerator and denominator to their lowest terms.  Use
 | 
			
		||||
  # Rational() instead.
 | 
			
		||||
  #
 | 
			
		||||
  def Rational.reduce(num, den = 1)
 | 
			
		||||
    raise ZeroDivisionError, "denominator is zero" if den == 0
 | 
			
		||||
  alias quof fdiv
 | 
			
		||||
 | 
			
		||||
    if den < 0
 | 
			
		||||
      num = -num
 | 
			
		||||
      den = -den
 | 
			
		||||
    end
 | 
			
		||||
    gcd = num.gcd(den)
 | 
			
		||||
    num = num.div(gcd)
 | 
			
		||||
    den = den.div(gcd)
 | 
			
		||||
    if den == 1 && defined?(Unify)
 | 
			
		||||
      num
 | 
			
		||||
    else
 | 
			
		||||
      new!(num, den)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  alias power! **
 | 
			
		||||
  alias rpower **
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Implements the constructor.  This method does not reduce to lowest terms or
 | 
			
		||||
  # check for division by zero.  Therefore #Rational() should be preferred in
 | 
			
		||||
  # normal use.
 | 
			
		||||
  #
 | 
			
		||||
  def Rational.new!(num, den = 1)
 | 
			
		||||
    new(num, den)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private_class_method :new
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # This method is actually private.
 | 
			
		||||
  #
 | 
			
		||||
  def initialize(num, den)
 | 
			
		||||
    if den < 0
 | 
			
		||||
      num = -num
 | 
			
		||||
      den = -den
 | 
			
		||||
    end
 | 
			
		||||
    if num.kind_of?(Integer) and den.kind_of?(Integer)
 | 
			
		||||
      @numerator = num
 | 
			
		||||
      @denominator = den
 | 
			
		||||
    else
 | 
			
		||||
      @numerator = num.to_i
 | 
			
		||||
      @denominator = den.to_i
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the addition of this value and +a+.
 | 
			
		||||
  #
 | 
			
		||||
  # Examples:
 | 
			
		||||
  #   r = Rational(3,4)      # -> Rational(3,4)
 | 
			
		||||
  #   r + 1                  # -> Rational(7,4)
 | 
			
		||||
  #   r + 0.5                # -> 1.25
 | 
			
		||||
  #
 | 
			
		||||
  def + (a)
 | 
			
		||||
    if a.kind_of?(Rational)
 | 
			
		||||
      num = @numerator * a.denominator
 | 
			
		||||
      num_a = a.numerator * @denominator
 | 
			
		||||
      Rational(num + num_a, @denominator * a.denominator)
 | 
			
		||||
    elsif a.kind_of?(Integer)
 | 
			
		||||
      self + Rational.new!(a, 1)
 | 
			
		||||
    elsif a.kind_of?(Float)
 | 
			
		||||
      Float(self) + a
 | 
			
		||||
    else
 | 
			
		||||
      x, y = a.coerce(self)
 | 
			
		||||
      x + y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the difference of this value and +a+.
 | 
			
		||||
  # subtracted.
 | 
			
		||||
  #
 | 
			
		||||
  # Examples:
 | 
			
		||||
  #   r = Rational(3,4)    # -> Rational(3,4)
 | 
			
		||||
  #   r - 1                # -> Rational(-1,4)
 | 
			
		||||
  #   r - 0.5              # -> 0.25
 | 
			
		||||
  #
 | 
			
		||||
  def - (a)
 | 
			
		||||
    if a.kind_of?(Rational)
 | 
			
		||||
      num = @numerator * a.denominator
 | 
			
		||||
      num_a = a.numerator * @denominator
 | 
			
		||||
      Rational(num - num_a, @denominator*a.denominator)
 | 
			
		||||
    elsif a.kind_of?(Integer)
 | 
			
		||||
      self - Rational.new!(a, 1)
 | 
			
		||||
    elsif a.kind_of?(Float)
 | 
			
		||||
      Float(self) - a
 | 
			
		||||
    else
 | 
			
		||||
      x, y = a.coerce(self)
 | 
			
		||||
      x - y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the product of this value and +a+.
 | 
			
		||||
  #
 | 
			
		||||
  # Examples:
 | 
			
		||||
  #   r = Rational(3,4)    # -> Rational(3,4)
 | 
			
		||||
  #   r * 2                # -> Rational(3,2)
 | 
			
		||||
  #   r * 4                # -> Rational(3,1)
 | 
			
		||||
  #   r * 0.5              # -> 0.375
 | 
			
		||||
  #   r * Rational(1,2)    # -> Rational(3,8)
 | 
			
		||||
  #
 | 
			
		||||
  def * (a)
 | 
			
		||||
    if a.kind_of?(Rational)
 | 
			
		||||
      num = @numerator * a.numerator
 | 
			
		||||
      den = @denominator * a.denominator
 | 
			
		||||
      Rational(num, den)
 | 
			
		||||
    elsif a.kind_of?(Integer)
 | 
			
		||||
      self * Rational.new!(a, 1)
 | 
			
		||||
    elsif a.kind_of?(Float)
 | 
			
		||||
      Float(self) * a
 | 
			
		||||
    else
 | 
			
		||||
      x, y = a.coerce(self)
 | 
			
		||||
      x * y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the quotient of this value and +a+.
 | 
			
		||||
  #   r = Rational(3,4)    # -> Rational(3,4)
 | 
			
		||||
  #   r / 2                # -> Rational(3,8)
 | 
			
		||||
  #   r / 2.0              # -> 0.375
 | 
			
		||||
  #   r / Rational(1,2)    # -> Rational(3,2)
 | 
			
		||||
  #
 | 
			
		||||
  def / (a)
 | 
			
		||||
    if a.kind_of?(Rational)
 | 
			
		||||
      num = @numerator * a.denominator
 | 
			
		||||
      den = @denominator * a.numerator
 | 
			
		||||
      Rational(num, den)
 | 
			
		||||
    elsif a.kind_of?(Integer)
 | 
			
		||||
      raise ZeroDivisionError, "division by zero" if a == 0
 | 
			
		||||
      self / Rational.new!(a, 1)
 | 
			
		||||
    elsif a.kind_of?(Float)
 | 
			
		||||
      Float(self) / a
 | 
			
		||||
    else
 | 
			
		||||
      x, y = a.coerce(self)
 | 
			
		||||
      x / y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns this value raised to the given power.
 | 
			
		||||
  #
 | 
			
		||||
  # Examples:
 | 
			
		||||
  #   r = Rational(3,4)    # -> Rational(3,4)
 | 
			
		||||
  #   r ** 2               # -> Rational(9,16)
 | 
			
		||||
  #   r ** 2.0             # -> 0.5625
 | 
			
		||||
  #   r ** Rational(1,2)   # -> 0.866025403784439
 | 
			
		||||
  #
 | 
			
		||||
  def ** (other)
 | 
			
		||||
    if other.kind_of?(Rational)
 | 
			
		||||
      Float(self) ** other
 | 
			
		||||
    elsif other.kind_of?(Integer)
 | 
			
		||||
      if other > 0
 | 
			
		||||
	num = @numerator ** other
 | 
			
		||||
	den = @denominator ** other
 | 
			
		||||
      elsif other < 0
 | 
			
		||||
	num = @denominator ** -other
 | 
			
		||||
	den = @numerator ** -other
 | 
			
		||||
      elsif other == 0
 | 
			
		||||
	num = 1
 | 
			
		||||
	den = 1
 | 
			
		||||
      end
 | 
			
		||||
      Rational.new!(num, den)
 | 
			
		||||
    elsif other.kind_of?(Float)
 | 
			
		||||
      Float(self) ** other
 | 
			
		||||
    else
 | 
			
		||||
      x, y = other.coerce(self)
 | 
			
		||||
      x ** y
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def div(other)
 | 
			
		||||
    (self / other).floor
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the remainder when this value is divided by +other+.
 | 
			
		||||
  #
 | 
			
		||||
  # Examples:
 | 
			
		||||
  #   r = Rational(7,4)    # -> Rational(7,4)
 | 
			
		||||
  #   r % Rational(1,2)    # -> Rational(1,4)
 | 
			
		||||
  #   r % 1                # -> Rational(3,4)
 | 
			
		||||
  #   r % Rational(1,7)    # -> Rational(1,28)
 | 
			
		||||
  #   r % 0.26             # -> 0.19
 | 
			
		||||
  #
 | 
			
		||||
  def % (other)
 | 
			
		||||
    value = (self / other).floor
 | 
			
		||||
    return self - other * value
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the quotient _and_ remainder.
 | 
			
		||||
  #
 | 
			
		||||
  # Examples:
 | 
			
		||||
  #   r = Rational(7,4)        # -> Rational(7,4)
 | 
			
		||||
  #   r.divmod Rational(1,2)   # -> [3, Rational(1,4)]
 | 
			
		||||
  #
 | 
			
		||||
  def divmod(other)
 | 
			
		||||
    value = (self / other).floor
 | 
			
		||||
    return value, self - other * value
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the absolute value.
 | 
			
		||||
  #
 | 
			
		||||
  def abs
 | 
			
		||||
    if @numerator > 0
 | 
			
		||||
      self
 | 
			
		||||
    else
 | 
			
		||||
      Rational.new!(-@numerator, @denominator)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns +true+ iff this value is numerically equal to +other+.
 | 
			
		||||
  #
 | 
			
		||||
  # But beware:
 | 
			
		||||
  #   Rational(1,2) == Rational(4,8)          # -> true
 | 
			
		||||
  #   Rational(1,2) == Rational.new!(4,8)     # -> false
 | 
			
		||||
  #
 | 
			
		||||
  # Don't use Rational.new!
 | 
			
		||||
  #
 | 
			
		||||
  def == (other)
 | 
			
		||||
    if other.kind_of?(Rational)
 | 
			
		||||
      @numerator == other.numerator and @denominator == other.denominator
 | 
			
		||||
    elsif other.kind_of?(Integer)
 | 
			
		||||
      self == Rational.new!(other, 1)
 | 
			
		||||
    elsif other.kind_of?(Float)
 | 
			
		||||
      Float(self) == other
 | 
			
		||||
    else
 | 
			
		||||
      other == self
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Standard comparison operator.
 | 
			
		||||
  #
 | 
			
		||||
  def <=> (other)
 | 
			
		||||
    if other.kind_of?(Rational)
 | 
			
		||||
      num = @numerator * other.denominator
 | 
			
		||||
      num_a = other.numerator * @denominator
 | 
			
		||||
      v = num - num_a
 | 
			
		||||
      if v > 0
 | 
			
		||||
	return 1
 | 
			
		||||
      elsif v < 0
 | 
			
		||||
	return  -1
 | 
			
		||||
      else
 | 
			
		||||
	return 0
 | 
			
		||||
      end
 | 
			
		||||
    elsif other.kind_of?(Integer)
 | 
			
		||||
      return self <=> Rational.new!(other, 1)
 | 
			
		||||
    elsif other.kind_of?(Float)
 | 
			
		||||
      return Float(self) <=> other
 | 
			
		||||
    elsif defined? other.coerce
 | 
			
		||||
      x, y = other.coerce(self)
 | 
			
		||||
      return x <=> y
 | 
			
		||||
    else
 | 
			
		||||
      return nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def coerce(other)
 | 
			
		||||
    if other.kind_of?(Float)
 | 
			
		||||
      return other, self.to_f
 | 
			
		||||
    elsif other.kind_of?(Integer)
 | 
			
		||||
      return Rational.new!(other, 1), self
 | 
			
		||||
    else
 | 
			
		||||
      super
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Converts the rational to an Integer.  Not the _nearest_ integer, the
 | 
			
		||||
  # truncated integer.  Study the following example carefully:
 | 
			
		||||
  #   Rational(+7,4).to_i             # -> 1
 | 
			
		||||
  #   Rational(-7,4).to_i             # -> -2
 | 
			
		||||
  #   (-1.75).to_i                    # -> -1
 | 
			
		||||
  #
 | 
			
		||||
  # In other words:
 | 
			
		||||
  #   Rational(-7,4) == -1.75                 # -> true
 | 
			
		||||
  #   Rational(-7,4).to_i == (-1.75).to_i     # false
 | 
			
		||||
  #
 | 
			
		||||
 | 
			
		||||
  def floor()
 | 
			
		||||
    @numerator.div(@denominator)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def ceil()
 | 
			
		||||
    -((-@numerator).div(@denominator))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def truncate()
 | 
			
		||||
    if @numerator < 0
 | 
			
		||||
      return -((-@numerator).div(@denominator))
 | 
			
		||||
    end
 | 
			
		||||
    @numerator.div(@denominator)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  alias_method :to_i, :truncate
 | 
			
		||||
 | 
			
		||||
  def round()
 | 
			
		||||
    if @numerator < 0
 | 
			
		||||
      num = -@numerator
 | 
			
		||||
      num = num * 2 + @denominator
 | 
			
		||||
      den = @denominator * 2
 | 
			
		||||
      -(num.div(den))
 | 
			
		||||
    else
 | 
			
		||||
      num = @numerator * 2 + @denominator
 | 
			
		||||
      den = @denominator * 2
 | 
			
		||||
      num.div(den)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Converts the rational to a Float.
 | 
			
		||||
  #
 | 
			
		||||
  def to_f
 | 
			
		||||
    @numerator.quof(@denominator)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns a string representation of the rational number.
 | 
			
		||||
  #
 | 
			
		||||
  # Example:
 | 
			
		||||
  #   Rational(3,4).to_s          #  "3/4"
 | 
			
		||||
  #   Rational(8).to_s            #  "8"
 | 
			
		||||
  #
 | 
			
		||||
  def to_s
 | 
			
		||||
    if @denominator == 1
 | 
			
		||||
      @numerator.to_s
 | 
			
		||||
    else
 | 
			
		||||
      @numerator.to_s+"/"+@denominator.to_s
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns +self+.
 | 
			
		||||
  #
 | 
			
		||||
  def to_r
 | 
			
		||||
    self
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns a reconstructable string representation:
 | 
			
		||||
  #
 | 
			
		||||
  #   Rational(5,8).inspect     # -> "Rational(5, 8)"
 | 
			
		||||
  #
 | 
			
		||||
  def inspect
 | 
			
		||||
    sprintf("Rational(%s, %s)", @numerator.inspect, @denominator.inspect)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns a hash code for the object.
 | 
			
		||||
  #
 | 
			
		||||
  def hash
 | 
			
		||||
    @numerator.hash ^ @denominator.hash
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  attr :numerator
 | 
			
		||||
  attr :denominator
 | 
			
		||||
 | 
			
		||||
  private :initialize
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class Integer
 | 
			
		||||
  #
 | 
			
		||||
  # In an integer, the value _is_ the numerator of its rational equivalent.
 | 
			
		||||
  # Therefore, this method returns +self+.
 | 
			
		||||
  #
 | 
			
		||||
  def numerator
 | 
			
		||||
    self
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # In an integer, the denominator is 1.  Therefore, this method returns 1.
 | 
			
		||||
  #
 | 
			
		||||
  def denominator
 | 
			
		||||
    1
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns a Rational representation of this integer.
 | 
			
		||||
  #
 | 
			
		||||
  def to_r
 | 
			
		||||
    Rational(self, 1)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the <em>greatest common denominator</em> of the two numbers (+self+
 | 
			
		||||
  # and +n+).
 | 
			
		||||
  #
 | 
			
		||||
  # Examples:
 | 
			
		||||
  #   72.gcd 168           # -> 24
 | 
			
		||||
  #   19.gcd 36            # -> 1
 | 
			
		||||
  #
 | 
			
		||||
  # The result is positive, no matter the sign of the arguments.
 | 
			
		||||
  #
 | 
			
		||||
  def gcd(other)
 | 
			
		||||
    min = self.abs
 | 
			
		||||
    max = other.abs
 | 
			
		||||
| 
						 | 
				
			
			@ -475,10 +29,6 @@ class Integer
 | 
			
		|||
    max
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Examples:
 | 
			
		||||
  #   6.lcm 7        # -> 42
 | 
			
		||||
  #   6.lcm 9        # -> 18
 | 
			
		||||
  #
 | 
			
		||||
  def lcm(other)
 | 
			
		||||
    if self.zero? or other.zero?
 | 
			
		||||
      0
 | 
			
		||||
| 
						 | 
				
			
			@ -487,14 +37,6 @@ class Integer
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Returns the GCD _and_ the LCM (see #gcd and #lcm) of the two arguments
 | 
			
		||||
  # (+self+ and +other+).  This is more efficient than calculating them
 | 
			
		||||
  # separately.
 | 
			
		||||
  #
 | 
			
		||||
  # Example:
 | 
			
		||||
  #   6.gcdlcm 9     # -> [3, 18]
 | 
			
		||||
  #
 | 
			
		||||
  def gcdlcm(other)
 | 
			
		||||
    gcd = self.gcd(other)
 | 
			
		||||
    if self.zero? or other.zero?
 | 
			
		||||
| 
						 | 
				
			
			@ -503,55 +45,5 @@ class Integer
 | 
			
		|||
      [gcd, (self.div(gcd) * other).abs]
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class Fixnum
 | 
			
		||||
  alias quof quo
 | 
			
		||||
  remove_method :quo
 | 
			
		||||
 | 
			
		||||
  # If Rational is defined, returns a Rational number instead of a Float.
 | 
			
		||||
  def quo(other)
 | 
			
		||||
    Rational.new!(self, 1) / other
 | 
			
		||||
  end
 | 
			
		||||
  alias rdiv quo
 | 
			
		||||
 | 
			
		||||
  # Returns a Rational number if the result is in fact rational (i.e. +other+ < 0).
 | 
			
		||||
  def rpower (other)
 | 
			
		||||
    if other >= 0
 | 
			
		||||
      self.power!(other)
 | 
			
		||||
    else
 | 
			
		||||
      Rational.new!(self, 1)**other
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class Bignum
 | 
			
		||||
  alias quof quo
 | 
			
		||||
  remove_method :quo
 | 
			
		||||
 | 
			
		||||
  # If Rational is defined, returns a Rational number instead of a Float.
 | 
			
		||||
  def quo(other)
 | 
			
		||||
    Rational.new!(self, 1) / other
 | 
			
		||||
  end
 | 
			
		||||
  alias rdiv quo
 | 
			
		||||
 | 
			
		||||
  # Returns a Rational number if the result is in fact rational (i.e. +other+ < 0).
 | 
			
		||||
  def rpower (other)
 | 
			
		||||
    if other >= 0
 | 
			
		||||
      self.power!(other)
 | 
			
		||||
    else
 | 
			
		||||
      Rational.new!(self, 1)**other
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
unless defined? 1.power!
 | 
			
		||||
  class Fixnum
 | 
			
		||||
    alias power! **
 | 
			
		||||
    alias ** rpower
 | 
			
		||||
  end
 | 
			
		||||
  class Bignum
 | 
			
		||||
    alias power! **
 | 
			
		||||
    alias ** rpower
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										69
									
								
								numeric.c
									
										
									
									
									
								
							
							
						
						
									
										69
									
								
								numeric.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -646,6 +646,17 @@ flo_div(VALUE x, VALUE y)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
flo_quo(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    return rb_funcall(x, '/', 1, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
flo_rdiv(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    return rb_funcall(rb_Rational1(x), '/', 1, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
flodivmod(double x, double y, double *divp, double *modp)
 | 
			
		||||
| 
						 | 
				
			
			@ -1699,6 +1710,17 @@ rb_num2ull(VALUE val)
 | 
			
		|||
 | 
			
		||||
#endif  /* HAVE_LONG_LONG */
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
num_numerator(VALUE num)
 | 
			
		||||
{
 | 
			
		||||
    return rb_funcall(rb_Rational1(num), rb_intern("numerator"), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
num_denominator(VALUE num)
 | 
			
		||||
{
 | 
			
		||||
    return rb_funcall(rb_Rational1(num), rb_intern("denominator"), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Document-class: Integer
 | 
			
		||||
| 
						 | 
				
			
			@ -1880,6 +1902,18 @@ int_chr(int argc, VALUE *argv, VALUE num)
 | 
			
		|||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
int_numerator(VALUE num)
 | 
			
		||||
{
 | 
			
		||||
    return num;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
int_denominator(VALUE num)
 | 
			
		||||
{
 | 
			
		||||
    return INT2FIX(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/********************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 * Document-class: Fixnum
 | 
			
		||||
| 
						 | 
				
			
			@ -1928,6 +1962,7 @@ rb_int_induced_from(VALUE klass, VALUE x)
 | 
			
		|||
      case T_BIGNUM:
 | 
			
		||||
	return x;
 | 
			
		||||
      case T_FLOAT:
 | 
			
		||||
      case T_RATIONAL:
 | 
			
		||||
	return rb_funcall(x, id_to_i, 0);
 | 
			
		||||
      default:
 | 
			
		||||
	rb_raise(rb_eTypeError, "failed to convert %s into Integer",
 | 
			
		||||
| 
						 | 
				
			
			@ -1948,6 +1983,7 @@ rb_flo_induced_from(VALUE klass, VALUE x)
 | 
			
		|||
    switch (TYPE(x)) {
 | 
			
		||||
      case T_FIXNUM:
 | 
			
		||||
      case T_BIGNUM:
 | 
			
		||||
      case T_RATIONAL:
 | 
			
		||||
	return rb_funcall(x, rb_intern("to_f"), 0);
 | 
			
		||||
      case T_FLOAT:
 | 
			
		||||
	return x;
 | 
			
		||||
| 
						 | 
				
			
			@ -2198,6 +2234,12 @@ fixdivmod(long x, long y, long *divp, long *modp)
 | 
			
		|||
 | 
			
		||||
static VALUE
 | 
			
		||||
fix_quo(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    return rb_funcall(rb_rational_raw1(x), '/', 1, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
fix_fdiv(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    if (FIXNUM_P(y)) {
 | 
			
		||||
	return DOUBLE2NUM((double)FIX2LONG(x) / (double)FIX2LONG(y));
 | 
			
		||||
| 
						 | 
				
			
			@ -2208,7 +2250,7 @@ fix_quo(VALUE x, VALUE y)
 | 
			
		|||
      case T_FLOAT:
 | 
			
		||||
	return DOUBLE2NUM((double)FIX2LONG(x) / RFLOAT_VALUE(y));
 | 
			
		||||
      default:
 | 
			
		||||
	return rb_num_coerce_bin(x, y, rb_intern("quo"));
 | 
			
		||||
	return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2392,6 +2434,9 @@ fix_pow(VALUE x, VALUE y)
 | 
			
		|||
    if (FIXNUM_P(y)) {
 | 
			
		||||
	long b = FIX2LONG(y);
 | 
			
		||||
 | 
			
		||||
	if (b < 0)
 | 
			
		||||
	  return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
 | 
			
		||||
 | 
			
		||||
	if (b == 0) return INT2FIX(1);
 | 
			
		||||
	if (b == 1) return x;
 | 
			
		||||
	if (a == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2405,13 +2450,14 @@ fix_pow(VALUE x, VALUE y)
 | 
			
		|||
	    else 
 | 
			
		||||
		return INT2FIX(-1);
 | 
			
		||||
	}
 | 
			
		||||
	if (b > 0) {
 | 
			
		||||
	    return int_pow(a, b);
 | 
			
		||||
	}
 | 
			
		||||
	return DOUBLE2NUM(pow((double)a, (double)b));
 | 
			
		||||
	return int_pow(a, b);
 | 
			
		||||
    }
 | 
			
		||||
    switch (TYPE(y)) {
 | 
			
		||||
      case T_BIGNUM:
 | 
			
		||||
 | 
			
		||||
	if (rb_funcall(y, '<', 1, INT2FIX(0)))
 | 
			
		||||
	  return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
 | 
			
		||||
 | 
			
		||||
	if (a == 0) return INT2FIX(0);
 | 
			
		||||
	if (a == 1) return INT2FIX(1);
 | 
			
		||||
	if (a == -1) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3117,6 +3163,7 @@ Init_Numeric(void)
 | 
			
		|||
    rb_define_method(rb_cNumeric, "<=>", num_cmp, 1);
 | 
			
		||||
    rb_define_method(rb_cNumeric, "eql?", num_eql, 1);
 | 
			
		||||
    rb_define_method(rb_cNumeric, "quo", num_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cNumeric, "rdiv", num_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cNumeric, "fdiv", num_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cNumeric, "div", num_div, 1);
 | 
			
		||||
    rb_define_method(rb_cNumeric, "divmod", num_divmod, 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -3136,6 +3183,9 @@ Init_Numeric(void)
 | 
			
		|||
    rb_define_method(rb_cNumeric, "truncate", num_truncate, 0);
 | 
			
		||||
    rb_define_method(rb_cNumeric, "step", num_step, -1);
 | 
			
		||||
 | 
			
		||||
    rb_define_method(rb_cNumeric, "numerator", num_numerator, 0);
 | 
			
		||||
    rb_define_method(rb_cNumeric, "denominator", num_denominator, 0);
 | 
			
		||||
 | 
			
		||||
    rb_cInteger = rb_define_class("Integer", rb_cNumeric);
 | 
			
		||||
    rb_undef_alloc_func(rb_cInteger);
 | 
			
		||||
    rb_undef_method(CLASS_OF(rb_cInteger), "new");
 | 
			
		||||
| 
						 | 
				
			
			@ -3163,6 +3213,9 @@ Init_Numeric(void)
 | 
			
		|||
    rb_define_singleton_method(rb_cFixnum, "induced_from", rb_fix_induced_from, 1);
 | 
			
		||||
    rb_define_singleton_method(rb_cInteger, "induced_from", rb_int_induced_from, 1);
 | 
			
		||||
 | 
			
		||||
    rb_define_method(rb_cInteger, "numerator", int_numerator, 0);
 | 
			
		||||
    rb_define_method(rb_cInteger, "denominator", int_denominator, 0);
 | 
			
		||||
 | 
			
		||||
    rb_define_method(rb_cFixnum, "to_s", fix_to_s, -1);
 | 
			
		||||
 | 
			
		||||
    rb_define_method(rb_cFixnum, "id2name", fix_id2name, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -3178,7 +3231,8 @@ Init_Numeric(void)
 | 
			
		|||
    rb_define_method(rb_cFixnum, "modulo", fix_mod, 1);
 | 
			
		||||
    rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1);
 | 
			
		||||
    rb_define_method(rb_cFixnum, "quo", fix_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cFixnum, "fdiv", fix_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cFixnum, "rdiv", fix_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cFixnum, "fdiv", fix_fdiv, 1);
 | 
			
		||||
    rb_define_method(rb_cFixnum, "**", fix_pow, 1);
 | 
			
		||||
 | 
			
		||||
    rb_define_method(rb_cFixnum, "abs", fix_abs, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -3233,6 +3287,9 @@ Init_Numeric(void)
 | 
			
		|||
    rb_define_method(rb_cFloat, "-", flo_minus, 1);
 | 
			
		||||
    rb_define_method(rb_cFloat, "*", flo_mul, 1);
 | 
			
		||||
    rb_define_method(rb_cFloat, "/", flo_div, 1);
 | 
			
		||||
    rb_define_method(rb_cFloat, "quo", flo_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cFloat, "rdiv", flo_rdiv, 1);
 | 
			
		||||
    rb_define_method(rb_cFloat, "fdiv", flo_quo, 1);
 | 
			
		||||
    rb_define_method(rb_cFloat, "%", flo_mod, 1);
 | 
			
		||||
    rb_define_method(rb_cFloat, "modulo", flo_mod, 1);
 | 
			
		||||
    rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1111
									
								
								rational.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1111
									
								
								rational.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1017
									
								
								test/ruby/test_complex.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1017
									
								
								test/ruby/test_complex.rb
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										971
									
								
								test/ruby/test_rational.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										971
									
								
								test/ruby/test_rational.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,971 @@
 | 
			
		|||
require 'test/unit'
 | 
			
		||||
 | 
			
		||||
class RationalSub < Rational; end
 | 
			
		||||
 | 
			
		||||
class Rational_Test < Test::Unit::TestCase
 | 
			
		||||
 | 
			
		||||
  def test_sub
 | 
			
		||||
    c = RationalSub.__send__(:new, 1)
 | 
			
		||||
    cc = RationalSub.__send__(:convert, 1)
 | 
			
		||||
    if defined?(RationalSub::Unify)
 | 
			
		||||
      assert_instance_of(Fixnum, c)
 | 
			
		||||
      assert_instance_of(Fixnum, cc)
 | 
			
		||||
    else
 | 
			
		||||
      assert_instance_of(RationalSub, c)
 | 
			
		||||
      assert_instance_of(RationalSub, cc)
 | 
			
		||||
 | 
			
		||||
      c2 = c + 1
 | 
			
		||||
      assert_instance_of(RationalSub, c2)
 | 
			
		||||
      c2 = c - 1
 | 
			
		||||
      assert_instance_of(RationalSub, c2)
 | 
			
		||||
 | 
			
		||||
      c3 = c - c2
 | 
			
		||||
      assert_instance_of(RationalSub, c3)
 | 
			
		||||
 | 
			
		||||
      s = Marshal.dump(c)
 | 
			
		||||
      c5 = Marshal.load(s)
 | 
			
		||||
      assert_equal(c, c5)
 | 
			
		||||
      assert_instance_of(RationalSub, c5)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_hash
 | 
			
		||||
    assert_instance_of(Fixnum, Rational(1,2).hash)
 | 
			
		||||
 | 
			
		||||
    h = {}
 | 
			
		||||
    h[Rational(0)] = 0
 | 
			
		||||
    h[Rational(1,1)] = 1
 | 
			
		||||
    h[Rational(2,1)] = 2
 | 
			
		||||
    h[Rational(3,1)] = 3
 | 
			
		||||
 | 
			
		||||
    assert_equal(4, h.size)
 | 
			
		||||
    assert_equal(2, h[Rational(2,1)])
 | 
			
		||||
 | 
			
		||||
    h[Rational(0,1)] = 9
 | 
			
		||||
    assert_equal(4, h.size)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_freeze
 | 
			
		||||
    c = Rational(1)
 | 
			
		||||
    c.freeze
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      assert_equal(true, c.frozen?)
 | 
			
		||||
    end
 | 
			
		||||
    assert_instance_of(String, c.to_s)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_new_bang # no unify & no reduce
 | 
			
		||||
    assert_instance_of(Rational, Rational.__send__(:new!, 2,1))
 | 
			
		||||
    assert_equal([2,1], Rational.__send__(:new!, 2,1).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([2,4],  Rational.__send__(:new!, 2,4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([-2,4], Rational.__send__(:new!, -2,4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([-2,4], Rational.__send__(:new!, 2,-4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([2,4], Rational.__send__(:new!, -2,-4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
 | 
			
		||||
    # to_i
 | 
			
		||||
    assert_equal([2,1], Rational.__send__(:new!, Rational(2)).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([2,3], Rational.__send__(:new!, Rational(2), Rational(3)).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([2,3], Rational.__send__(:new!, 2, Rational(3)).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
 | 
			
		||||
    assert_equal([1,1], Rational.__send__(:new!, 1.1).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([-1,1], Rational.__send__(:new!, -1.1).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([1,1], Rational.__send__(:new!, '1').
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([0,1], Rational.__send__(:new!, nil).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
=begin
 | 
			
		||||
  def test_reduce
 | 
			
		||||
    if defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Fixnum, Rational.__send__(:reduce, 2,1))
 | 
			
		||||
    else
 | 
			
		||||
      assert_instance_of(Rational, Rational.__send__(:reduce, 2,1))
 | 
			
		||||
      assert_instance_of(Rational, Rational.__send__(:reduce, 2,1))
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal([2,1], Rational.__send__(:reduce, 2,1).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([1,2], Rational.__send__(:reduce, 2,4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([-1,2], Rational.__send__(:reduce, -2,4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([-1,2], Rational.__send__(:reduce, 2,-4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([1,2], Rational.__send__(:reduce, -2,-4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:reduce, Rational(1,2),2)}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:reduce, 2,Rational(1,2))}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.
 | 
			
		||||
      __send__(:reduce, Rational(1,2),Rational(1,2))}
 | 
			
		||||
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:reduce, 1.1)}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:reduce, -1.1)}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:reduce, '1')}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:reduce, nil)}
 | 
			
		||||
  end
 | 
			
		||||
=end
 | 
			
		||||
 | 
			
		||||
  def test_new
 | 
			
		||||
    if defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Fixnum, Rational.__send__(:new, 2,1))
 | 
			
		||||
    else
 | 
			
		||||
      assert_instance_of(Rational, Rational.__send__(:new, 2,1))
 | 
			
		||||
      assert_equal([2,1], Rational.__send__(:new, 2,1).
 | 
			
		||||
		   instance_eval{[numerator, denominator]})
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal([1,2], Rational.__send__(:new, 2,4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([-1,2], Rational.__send__(:new, -2,4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([-1,2], Rational.__send__(:new, 2,-4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
    assert_equal([1,2], Rational.__send__(:new, -2,-4).
 | 
			
		||||
		 instance_eval{[numerator, denominator]})
 | 
			
		||||
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:new, Rational(1,2),2)}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:new, 2,Rational(1,2))}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:new, Rational(1,2),Rational(1,2))}
 | 
			
		||||
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:new, 1.1)}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:new, -1.1)}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:new, '1')}
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:new, nil)}
 | 
			
		||||
=begin
 | 
			
		||||
    assert_raise(ArgumentError){Rational.__send__(:new, Rational(1))}
 | 
			
		||||
    if defined?(Complex)
 | 
			
		||||
      assert_raise(ArgumentError){Rational.__send__(:new, Complex(1))}
 | 
			
		||||
    end
 | 
			
		||||
=end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_conv
 | 
			
		||||
    c = Rational(0,1)
 | 
			
		||||
    assert_equal(Rational.__send__(:new, 0,1), c)
 | 
			
		||||
 | 
			
		||||
    c = Rational(2**32, 2**32)
 | 
			
		||||
    assert_equal(Rational.__send__(:new, 2**32,2**32), c)
 | 
			
		||||
    assert_equal([1,1], [c.numerator,c.denominator])
 | 
			
		||||
 | 
			
		||||
    c = Rational(-2**32, 2**32)
 | 
			
		||||
    assert_equal(Rational.__send__(:new, -2**32,2**32), c)
 | 
			
		||||
    assert_equal([-1,1], [c.numerator,c.denominator])
 | 
			
		||||
 | 
			
		||||
    c = Rational(2**32, -2**32)
 | 
			
		||||
    assert_equal(Rational.__send__(:new, 2**32,-2**32), c)
 | 
			
		||||
    assert_equal([-1,1], [c.numerator,c.denominator])
 | 
			
		||||
 | 
			
		||||
    c = Rational(-2**32, -2**32)
 | 
			
		||||
    assert_equal(Rational.__send__(:new, -2**32,-2**32), c)
 | 
			
		||||
    assert_equal([1,1], [c.numerator,c.denominator])
 | 
			
		||||
 | 
			
		||||
    c = Rational(Rational(1,2),2)
 | 
			
		||||
    assert_equal(Rational.__send__(:new, 1,4), c)
 | 
			
		||||
 | 
			
		||||
    c = Rational(2,Rational(1,2))
 | 
			
		||||
    assert_equal(Rational.__send__(:new, 4), c)
 | 
			
		||||
 | 
			
		||||
    c = Rational(Rational(1,2),Rational(1,2))
 | 
			
		||||
    assert_equal(Rational.__send__(:new, 1), c)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational.__send__(:new, 1),Rational(1))
 | 
			
		||||
    assert_equal(1.1.to_r,Rational(1.1))
 | 
			
		||||
    assert_equal(Rational.__send__(:new, 1),Rational('1'))
 | 
			
		||||
    assert_raise(ArgumentError){Rational(nil)}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_attr
 | 
			
		||||
    c = Rational(4)
 | 
			
		||||
 | 
			
		||||
    assert_equal(4, c.numerator)
 | 
			
		||||
    assert_equal(1, c.denominator)
 | 
			
		||||
 | 
			
		||||
    c = Rational(4,5)
 | 
			
		||||
 | 
			
		||||
    assert_equal(4, c.numerator)
 | 
			
		||||
    assert_equal(5, c.denominator)
 | 
			
		||||
 | 
			
		||||
    c = Rational.__send__(:new, 4)
 | 
			
		||||
 | 
			
		||||
    assert_equal(4, c.numerator)
 | 
			
		||||
    assert_equal(1, c.denominator)
 | 
			
		||||
 | 
			
		||||
    c = Rational.__send__(:new, 4,5)
 | 
			
		||||
 | 
			
		||||
    assert_equal(4, c.numerator)
 | 
			
		||||
    assert_equal(5, c.denominator)
 | 
			
		||||
 | 
			
		||||
    c = Rational.__send__(:new!, 4)
 | 
			
		||||
 | 
			
		||||
    assert_equal(4, c.numerator)
 | 
			
		||||
    assert_equal(1, c.denominator)
 | 
			
		||||
 | 
			
		||||
    c = Rational.__send__(:new!, 4,5)
 | 
			
		||||
 | 
			
		||||
    assert_equal(4, c.numerator)
 | 
			
		||||
    assert_equal(5, c.denominator)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_attr2
 | 
			
		||||
    c = Rational(1)
 | 
			
		||||
 | 
			
		||||
    if defined?(Rational::Unify)
 | 
			
		||||
      assert_equal(true, c.scalar?)
 | 
			
		||||
=begin
 | 
			
		||||
      assert_equal(true, c.finite?)
 | 
			
		||||
      assert_equal(false, c.infinite?)
 | 
			
		||||
      assert_equal(false, c.nan?)
 | 
			
		||||
      assert_equal(true, c.integer?)
 | 
			
		||||
      assert_equal(false, c.float?)
 | 
			
		||||
      assert_equal(true, c.rational?)
 | 
			
		||||
      assert_equal(true, c.real?)
 | 
			
		||||
      assert_equal(false, c.complex?)
 | 
			
		||||
      assert_equal(true, c.exact?)
 | 
			
		||||
      assert_equal(false, c.inexact?)
 | 
			
		||||
=end
 | 
			
		||||
    else
 | 
			
		||||
      assert_equal(true, c.scalar?)
 | 
			
		||||
=begin
 | 
			
		||||
      assert_equal(true, c.finite?)
 | 
			
		||||
      assert_equal(false, c.infinite?)
 | 
			
		||||
      assert_equal(false, c.nan?)
 | 
			
		||||
      assert_equal(false, c.integer?)
 | 
			
		||||
      assert_equal(false, c.float?)
 | 
			
		||||
      assert_equal(true, c.rational?)
 | 
			
		||||
      assert_equal(true, c.real?)
 | 
			
		||||
      assert_equal(false, c.complex?)
 | 
			
		||||
      assert_equal(true, c.exact?)
 | 
			
		||||
      assert_equal(false, c.inexact?)
 | 
			
		||||
=end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
=begin
 | 
			
		||||
    assert_equal(true, Rational(0).positive?)
 | 
			
		||||
    assert_equal(true, Rational(1).positive?)
 | 
			
		||||
    assert_equal(false, Rational(-1).positive?)
 | 
			
		||||
    assert_equal(false, Rational(0).negative?)
 | 
			
		||||
    assert_equal(false, Rational(1).negative?)
 | 
			
		||||
    assert_equal(true, Rational(-1).negative?)
 | 
			
		||||
 | 
			
		||||
    assert_equal(0, Rational(0).sign)
 | 
			
		||||
    assert_equal(1, Rational(2).sign)
 | 
			
		||||
    assert_equal(-1, Rational(-2).sign)
 | 
			
		||||
=end
 | 
			
		||||
 | 
			
		||||
    assert_equal(true, Rational(0).zero?)
 | 
			
		||||
    assert_equal(true, Rational(0,1).zero?)
 | 
			
		||||
    assert_equal(false, Rational(1,1).zero?)
 | 
			
		||||
 | 
			
		||||
    assert_equal(nil, Rational(0).nonzero?)
 | 
			
		||||
    assert_equal(nil, Rational(0,1).nonzero?)
 | 
			
		||||
    assert_equal(Rational(1,1), Rational(1,1).nonzero?)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_uplus
 | 
			
		||||
    assert_equal(Rational(1), +Rational(1))
 | 
			
		||||
    assert_equal(Rational(-1), +Rational(-1))
 | 
			
		||||
    assert_equal(Rational(1,1), +Rational(1,1))
 | 
			
		||||
    assert_equal(Rational(-1,1), +Rational(-1,1))
 | 
			
		||||
    assert_equal(Rational(-1,1), +Rational(1,-1))
 | 
			
		||||
    assert_equal(Rational(1,1), +Rational(-1,-1))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_negate
 | 
			
		||||
    assert_equal(Rational(-1), -Rational(1))
 | 
			
		||||
    assert_equal(Rational(1), -Rational(-1))
 | 
			
		||||
    assert_equal(Rational(-1,1), -Rational(1,1))
 | 
			
		||||
    assert_equal(Rational(1,1), -Rational(-1,1))
 | 
			
		||||
    assert_equal(Rational(1,1), -Rational(1,-1))
 | 
			
		||||
    assert_equal(Rational(-1,1), -Rational(-1,-1))
 | 
			
		||||
 | 
			
		||||
=begin
 | 
			
		||||
    assert_equal(0, Rational(0).negate)
 | 
			
		||||
    assert_equal(-2, Rational(2).negate)
 | 
			
		||||
    assert_equal(2, Rational(-2).negate)
 | 
			
		||||
=end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_add
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(7,6), c + c2)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(5,2), c + 2)
 | 
			
		||||
    assert_equal(2.5, c + 2.0)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_sub
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(-1,6), c - c2)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(-3,2), c - 2)
 | 
			
		||||
    assert_equal(-1.5, c - 2.0)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_mul
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,3), c * c2)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,1), c * 2)
 | 
			
		||||
    assert_equal(1.0, c * 2.0)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_div
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(3,4), c / c2)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,4), c / 2)
 | 
			
		||||
    assert_equal(0.25, c / 2.0)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def assert_eql(exp, act, *args)
 | 
			
		||||
    unless Array === exp
 | 
			
		||||
      exp = [exp]
 | 
			
		||||
    end
 | 
			
		||||
    unless Array === act
 | 
			
		||||
      act = [act]
 | 
			
		||||
    end
 | 
			
		||||
    exp.zip(act).each do |e, a|
 | 
			
		||||
      na = [e, a] + args
 | 
			
		||||
      assert_equal(*na)
 | 
			
		||||
      na = [e.class, a] + args
 | 
			
		||||
      assert_instance_of(*na)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_idiv
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_eql(0, c.div(c2))
 | 
			
		||||
    assert_eql(0, c.div(2))
 | 
			
		||||
    assert_eql(0, c.div(2.0))
 | 
			
		||||
 | 
			
		||||
    c = Rational(301,100)
 | 
			
		||||
    c2 = Rational(7,5)
 | 
			
		||||
 | 
			
		||||
    assert_equal(2, c.div(c2))
 | 
			
		||||
    assert_equal(-3, c.div(-c2))
 | 
			
		||||
    assert_equal(-3, (-c).div(c2))
 | 
			
		||||
    assert_equal(2, (-c).div(-c2))
 | 
			
		||||
 | 
			
		||||
    c = Rational(301,100)
 | 
			
		||||
    c2 = Rational(2)
 | 
			
		||||
 | 
			
		||||
    assert_equal(1, c.div(c2))
 | 
			
		||||
    assert_equal(-2, c.div(-c2))
 | 
			
		||||
    assert_equal(-2, (-c).div(c2))
 | 
			
		||||
    assert_equal(1, (-c).div(-c2))
 | 
			
		||||
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      c = Rational(11)
 | 
			
		||||
      c2 = Rational(3)
 | 
			
		||||
 | 
			
		||||
      assert_equal(3, c.div(c2))
 | 
			
		||||
      assert_equal(-4, c.div(-c2))
 | 
			
		||||
      assert_equal(-4, (-c).div(c2))
 | 
			
		||||
      assert_equal(3, (-c).div(-c2))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_divmod
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_eql([0, Rational(1,2)], c.divmod(c2))
 | 
			
		||||
    assert_eql([0, Rational(1,2)], c.divmod(2))
 | 
			
		||||
    assert_eql([0, 0.5], c.divmod(2.0))
 | 
			
		||||
 | 
			
		||||
    c = Rational(301,100)
 | 
			
		||||
    c2 = Rational(7,5)
 | 
			
		||||
 | 
			
		||||
    assert_equal([2, Rational(21,100)], c.divmod(c2))
 | 
			
		||||
    assert_equal([-3, Rational(-119,100)], c.divmod(-c2))
 | 
			
		||||
    assert_equal([-3, Rational(119,100)], (-c).divmod(c2))
 | 
			
		||||
    assert_equal([2, Rational(-21,100)], (-c).divmod(-c2))
 | 
			
		||||
 | 
			
		||||
    c = Rational(301,100)
 | 
			
		||||
    c2 = Rational(2)
 | 
			
		||||
 | 
			
		||||
    assert_equal([1, Rational(101,100)], c.divmod(c2))
 | 
			
		||||
    assert_equal([-2, Rational(-99,100)], c.divmod(-c2))
 | 
			
		||||
    assert_equal([-2, Rational(99,100)], (-c).divmod(c2))
 | 
			
		||||
    assert_equal([1, Rational(-101,100)], (-c).divmod(-c2))
 | 
			
		||||
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      c = Rational(11)
 | 
			
		||||
      c2 = Rational(3)
 | 
			
		||||
 | 
			
		||||
      assert_equal([3,2], c.divmod(c2))
 | 
			
		||||
      assert_equal([-4,-1], c.divmod(-c2))
 | 
			
		||||
      assert_equal([-4,1], (-c).divmod(c2))
 | 
			
		||||
      assert_equal([3,-2], (-c).divmod(-c2))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
=begin
 | 
			
		||||
  def test_quot
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_eql(0, c.quot(c2))
 | 
			
		||||
    assert_eql(0, c.quot(2))
 | 
			
		||||
    assert_eql(0, c.quot(2.0))
 | 
			
		||||
 | 
			
		||||
    c = Rational(301,100)
 | 
			
		||||
    c2 = Rational(7,5)
 | 
			
		||||
 | 
			
		||||
    assert_equal(2, c.quot(c2))
 | 
			
		||||
    assert_equal(-2, c.quot(-c2))
 | 
			
		||||
    assert_equal(-2, (-c).quot(c2))
 | 
			
		||||
    assert_equal(2, (-c).quot(-c2))
 | 
			
		||||
 | 
			
		||||
    c = Rational(301,100)
 | 
			
		||||
    c2 = Rational(2)
 | 
			
		||||
 | 
			
		||||
    assert_equal(1, c.quot(c2))
 | 
			
		||||
    assert_equal(-1, c.quot(-c2))
 | 
			
		||||
    assert_equal(-1, (-c).quot(c2))
 | 
			
		||||
    assert_equal(1, (-c).quot(-c2))
 | 
			
		||||
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      c = Rational(11)
 | 
			
		||||
      c2 = Rational(3)
 | 
			
		||||
 | 
			
		||||
      assert_equal(3, c.quot(c2))
 | 
			
		||||
      assert_equal(-3, c.quot(-c2))
 | 
			
		||||
      assert_equal(-3, (-c).quot(c2))
 | 
			
		||||
      assert_equal(3, (-c).quot(-c2))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_quotrem
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_eql([0, Rational(1,2)], c.quotrem(c2))
 | 
			
		||||
    assert_eql([0, Rational(1,2)], c.quotrem(2))
 | 
			
		||||
    assert_eql([0, 0.5], c.quotrem(2.0))
 | 
			
		||||
 | 
			
		||||
    c = Rational(301,100)
 | 
			
		||||
    c2 = Rational(7,5)
 | 
			
		||||
 | 
			
		||||
    assert_equal([2, Rational(21,100)], c.quotrem(c2))
 | 
			
		||||
    assert_equal([-2, Rational(21,100)], c.quotrem(-c2))
 | 
			
		||||
    assert_equal([-2, Rational(-21,100)], (-c).quotrem(c2))
 | 
			
		||||
    assert_equal([2, Rational(-21,100)], (-c).quotrem(-c2))
 | 
			
		||||
 | 
			
		||||
    c = Rational(301,100)
 | 
			
		||||
    c2 = Rational(2)
 | 
			
		||||
 | 
			
		||||
    assert_equal([1, Rational(101,100)], c.quotrem(c2))
 | 
			
		||||
    assert_equal([-1, Rational(101,100)], c.quotrem(-c2))
 | 
			
		||||
    assert_equal([-1, Rational(-101,100)], (-c).quotrem(c2))
 | 
			
		||||
    assert_equal([1, Rational(-101,100)], (-c).quotrem(-c2))
 | 
			
		||||
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      c = Rational(11)
 | 
			
		||||
      c2 = Rational(3)
 | 
			
		||||
 | 
			
		||||
      assert_equal([3,2], c.quotrem(c2))
 | 
			
		||||
      assert_equal([-3,2], c.quotrem(-c2))
 | 
			
		||||
      assert_equal([-3,-2], (-c).quotrem(c2))
 | 
			
		||||
      assert_equal([3,-2], (-c).quotrem(-c2))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
=end
 | 
			
		||||
 | 
			
		||||
  def test_quo
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(3,4), c.quo(c2))
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,4), c.quo(2))
 | 
			
		||||
    assert_equal(Rational(0.25), c.quo(2.0))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_rdiv
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(3,4), c.rdiv(c2))
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,4), c.rdiv(2))
 | 
			
		||||
    assert_equal(Rational(0.25), c.rdiv(2.0))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_fdiv
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    assert_equal(0.75, c.fdiv(c2))
 | 
			
		||||
 | 
			
		||||
    assert_equal(0.25, c.fdiv(2))
 | 
			
		||||
    assert_equal(0.25, c.fdiv(2.0))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_expt
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
    c2 = Rational(2,3)
 | 
			
		||||
 | 
			
		||||
    r = c ** c2
 | 
			
		||||
    assert_in_delta(0.6299, r, 0.001)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,4), c ** 2)
 | 
			
		||||
    assert_equal(Rational(4), c ** -2)
 | 
			
		||||
    assert_equal(Rational(1,4), (-c) ** 2)
 | 
			
		||||
    assert_equal(Rational(4), (-c) ** -2)
 | 
			
		||||
 | 
			
		||||
    assert_equal(0.25, c ** 2.0)
 | 
			
		||||
    assert_equal(4.0, c ** -2.0)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,4), c ** Rational(2))
 | 
			
		||||
    assert_equal(Rational(4), c ** Rational(-2))
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1), 0 ** Rational(0))
 | 
			
		||||
    assert_equal(Rational(1), Rational(0) ** 0)
 | 
			
		||||
    assert_equal(Rational(1), Rational(0) ** Rational(0))
 | 
			
		||||
 | 
			
		||||
    # p ** p
 | 
			
		||||
    x = 2 ** Rational(2)
 | 
			
		||||
    assert_equal(Rational(4), x)
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Rational, x)
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(4, x.numerator)
 | 
			
		||||
    assert_equal(1, x.denominator)
 | 
			
		||||
 | 
			
		||||
    x = Rational(2) ** 2
 | 
			
		||||
    assert_equal(Rational(4), x)
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Rational, x)
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(4, x.numerator)
 | 
			
		||||
    assert_equal(1, x.denominator)
 | 
			
		||||
 | 
			
		||||
    x = Rational(2) ** Rational(2)
 | 
			
		||||
    assert_equal(Rational(4), x)
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Rational, x)
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(4, x.numerator)
 | 
			
		||||
    assert_equal(1, x.denominator)
 | 
			
		||||
 | 
			
		||||
    # -p ** p
 | 
			
		||||
    x = (-2) ** Rational(2)
 | 
			
		||||
    assert_equal(Rational(4), x)
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Rational, x)
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(4, x.numerator)
 | 
			
		||||
    assert_equal(1, x.denominator)
 | 
			
		||||
 | 
			
		||||
    x = Rational(-2) ** 2
 | 
			
		||||
    assert_equal(Rational(4), x)
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Rational, x)
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(4, x.numerator)
 | 
			
		||||
    assert_equal(1, x.denominator)
 | 
			
		||||
 | 
			
		||||
    x = Rational(-2) ** Rational(2)
 | 
			
		||||
    assert_equal(Rational(4), x)
 | 
			
		||||
    unless defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Rational, x)
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(4, x.numerator)
 | 
			
		||||
    assert_equal(1, x.denominator)
 | 
			
		||||
 | 
			
		||||
    # p ** -p
 | 
			
		||||
    x = 2 ** Rational(-2)
 | 
			
		||||
    assert_equal(Rational(1,4), x)
 | 
			
		||||
    assert_instance_of(Rational, x)
 | 
			
		||||
    assert_equal(1, x.numerator)
 | 
			
		||||
    assert_equal(4, x.denominator)
 | 
			
		||||
 | 
			
		||||
    x = Rational(2) ** -2
 | 
			
		||||
    assert_equal(Rational(1,4), x)
 | 
			
		||||
    assert_instance_of(Rational, x)
 | 
			
		||||
    assert_equal(1, x.numerator)
 | 
			
		||||
    assert_equal(4, x.denominator)
 | 
			
		||||
 | 
			
		||||
    x = Rational(2) ** Rational(-2)
 | 
			
		||||
    assert_equal(Rational(1,4), x)
 | 
			
		||||
    assert_instance_of(Rational, x)
 | 
			
		||||
    assert_equal(1, x.numerator)
 | 
			
		||||
    assert_equal(4, x.denominator)
 | 
			
		||||
 | 
			
		||||
    # -p ** -p
 | 
			
		||||
    x = (-2) ** Rational(-2)
 | 
			
		||||
    assert_equal(Rational(1,4), x)
 | 
			
		||||
    assert_instance_of(Rational, x)
 | 
			
		||||
    assert_equal(1, x.numerator)
 | 
			
		||||
    assert_equal(4, x.denominator)
 | 
			
		||||
 | 
			
		||||
    x = Rational(-2) ** -2
 | 
			
		||||
    assert_equal(Rational(1,4), x)
 | 
			
		||||
    assert_instance_of(Rational, x)
 | 
			
		||||
    assert_equal(1, x.numerator)
 | 
			
		||||
    assert_equal(4, x.denominator)
 | 
			
		||||
 | 
			
		||||
    x = Rational(-2) ** Rational(-2)
 | 
			
		||||
    assert_equal(Rational(1,4), x)
 | 
			
		||||
    assert_instance_of(Rational, x)
 | 
			
		||||
    assert_equal(1, x.numerator)
 | 
			
		||||
    assert_equal(4, x.denominator)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_cmp
 | 
			
		||||
    assert_equal(-1, Rational(-1) <=> Rational(0))
 | 
			
		||||
    assert_equal(0, Rational(0) <=> Rational(0))
 | 
			
		||||
    assert_equal(+1, Rational(+1) <=> Rational(0))
 | 
			
		||||
 | 
			
		||||
    assert_equal(-1, Rational(-1) <=> 0)
 | 
			
		||||
    assert_equal(0, Rational(0) <=> 0)
 | 
			
		||||
    assert_equal(+1, Rational(+1) <=> 0)
 | 
			
		||||
 | 
			
		||||
    assert_equal(-1, Rational(-1) <=> 0.0)
 | 
			
		||||
    assert_equal(0, Rational(0) <=> 0.0)
 | 
			
		||||
    assert_equal(+1, Rational(+1) <=> 0.0)
 | 
			
		||||
 | 
			
		||||
    assert_equal(-1, Rational(1,2) <=> Rational(2,3))
 | 
			
		||||
    assert_equal(0, Rational(2,3) <=> Rational(2,3))
 | 
			
		||||
    assert_equal(+1, Rational(2,3) <=> Rational(1,2))
 | 
			
		||||
 | 
			
		||||
    f = 2**30-1
 | 
			
		||||
    b = 2**30
 | 
			
		||||
 | 
			
		||||
    assert_equal(0, Rational(f) <=> Rational(f))
 | 
			
		||||
    assert_equal(-1, Rational(f) <=> Rational(b))
 | 
			
		||||
    assert_equal(+1, Rational(b) <=> Rational(f))
 | 
			
		||||
    assert_equal(0, Rational(b) <=> Rational(b))
 | 
			
		||||
 | 
			
		||||
    assert_equal(-1, Rational(f-1) <=> Rational(f))
 | 
			
		||||
    assert_equal(+1, Rational(f) <=> Rational(f-1))
 | 
			
		||||
    assert_equal(-1, Rational(b-1) <=> Rational(b))
 | 
			
		||||
    assert_equal(+1, Rational(b) <=> Rational(b-1))
 | 
			
		||||
 | 
			
		||||
    assert_equal(false, Rational(0) < Rational(0))
 | 
			
		||||
    assert_equal(true, Rational(0) <= Rational(0))
 | 
			
		||||
    assert_equal(true, Rational(0) >= Rational(0))
 | 
			
		||||
    assert_equal(false, Rational(0) > Rational(0))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_equal
 | 
			
		||||
    assert(Rational(1,1) == Rational(1))
 | 
			
		||||
    assert(Rational(1,1) == Rational.__send__(:new, 1))
 | 
			
		||||
    assert(Rational(1,1) == Rational.__send__(:new, 1,1))
 | 
			
		||||
    assert(Rational(1,1) == Rational.__send__(:new!, 1))
 | 
			
		||||
    assert(Rational(1,1) == Rational.__send__(:new!, 1,1))
 | 
			
		||||
 | 
			
		||||
    assert(Rational(-1,1) == Rational(-1))
 | 
			
		||||
    assert(Rational(-1,1) == Rational.__send__(:new, -1))
 | 
			
		||||
    assert(Rational(-1,1) == Rational.__send__(:new, -1,1))
 | 
			
		||||
    assert(Rational(-1,1) == Rational.__send__(:new!, -1))
 | 
			
		||||
    assert(Rational(-1,1) == Rational.__send__(:new!, -1,1))
 | 
			
		||||
 | 
			
		||||
    assert_equal(false, Rational(2,1) == Rational(1))
 | 
			
		||||
    assert_equal(true, Rational(2,1) != Rational(1))
 | 
			
		||||
    assert_equal(false, Rational(1) == nil)
 | 
			
		||||
    assert_equal(false, Rational(1) == '')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_unify
 | 
			
		||||
    if defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Fixnum, Rational(1,2) + Rational(1,2))
 | 
			
		||||
      assert_instance_of(Fixnum, Rational(1,2) - Rational(1,2))
 | 
			
		||||
      assert_instance_of(Fixnum, Rational(1,2) * 2)
 | 
			
		||||
      assert_instance_of(Fixnum, Rational(1,2) / Rational(1,2))
 | 
			
		||||
      assert_instance_of(Fixnum, Rational(1,2).div(Rational(1,2)))
 | 
			
		||||
      assert_instance_of(Fixnum, Rational(1,2).quo(Rational(1,2)))
 | 
			
		||||
      assert_instance_of(Fixnum, Rational(1,2) ** -2)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_s
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
 | 
			
		||||
    assert_instance_of(String, c.to_s)
 | 
			
		||||
    assert_equal('1/2', c.to_s)
 | 
			
		||||
 | 
			
		||||
    assert_equal('0', Rational(0,2).to_s)
 | 
			
		||||
    assert_equal('0', Rational(0,-2).to_s)
 | 
			
		||||
    assert_equal('1/2', Rational(1,2).to_s)
 | 
			
		||||
    assert_equal('-1/2', Rational(-1,2).to_s)
 | 
			
		||||
    assert_equal('1/2', Rational(-1,-2).to_s)
 | 
			
		||||
    assert_equal('-1/2', Rational(1,-2).to_s)
 | 
			
		||||
    assert_equal('1/2', Rational(-1,-2).to_s)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_inspect
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
 | 
			
		||||
    assert_instance_of(String, c.inspect)
 | 
			
		||||
    assert_equal('Rational(1, 2)', c.inspect)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_marshal
 | 
			
		||||
    c = Rational(1,2)
 | 
			
		||||
 | 
			
		||||
    s = Marshal.dump(c)
 | 
			
		||||
    c2 = Marshal.load(s)
 | 
			
		||||
    assert_equal(c, c2)
 | 
			
		||||
    assert_instance_of(Rational, c2)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_parse
 | 
			
		||||
    assert_equal(Rational(0), ''.to_r)
 | 
			
		||||
    assert_equal(Rational(0), ' '.to_r)
 | 
			
		||||
    assert_equal(Rational(5), '5'.to_r)
 | 
			
		||||
    assert_equal(Rational(-5), '-5'.to_r)
 | 
			
		||||
    assert_equal(Rational(5,3), '5/3'.to_r)
 | 
			
		||||
    assert_equal(Rational(-5,3), '-5/3'.to_r)
 | 
			
		||||
    assert_equal(Rational(5,-3), '5/-3'.to_r)
 | 
			
		||||
    assert_equal(Rational(-5,-3), '-5/-3'.to_r)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(5), '5.0'.to_r)
 | 
			
		||||
    assert_equal(Rational(-5), '-5.0'.to_r)
 | 
			
		||||
    assert_equal(Rational(5,3), '5.0/3'.to_r)
 | 
			
		||||
    assert_equal(Rational(-5,3), '-5.0/3'.to_r)
 | 
			
		||||
    assert_equal(Rational(5,-3), '5.0/-3'.to_r)
 | 
			
		||||
    assert_equal(Rational(-5,-3), '-5.0/-3'.to_r)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(5), '5e0'.to_r)
 | 
			
		||||
    assert_equal(Rational(-5), '-5e0'.to_r)
 | 
			
		||||
    assert_equal(Rational(5,3), '5e0/3'.to_r)
 | 
			
		||||
    assert_equal(Rational(-5,3), '-5e0/3'.to_r)
 | 
			
		||||
    assert_equal(Rational(5,-3), '5e0/-3'.to_r)
 | 
			
		||||
    assert_equal(Rational(-5,-3), '-5e0/-3'.to_r)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(33,100), '0.33'.to_r)
 | 
			
		||||
    assert_equal(Rational(-33,100), '-0.33'.to_r)
 | 
			
		||||
    assert_equal(Rational(-33,100), '-0.3_3'.to_r)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,2), '5e-1'.to_r)
 | 
			
		||||
    assert_equal(Rational(50), '5e+1'.to_r)
 | 
			
		||||
    assert_equal(Rational(1,2), '5.0e-1'.to_r)
 | 
			
		||||
    assert_equal(Rational(50), '5.0e+1'.to_r)
 | 
			
		||||
    assert_equal(Rational(50), '5e1'.to_r)
 | 
			
		||||
    assert_equal(Rational(50), '5E1'.to_r)
 | 
			
		||||
    assert_equal(Rational(500), '5e2'.to_r)
 | 
			
		||||
    assert_equal(Rational(5000), '5e3'.to_r)
 | 
			
		||||
    assert_equal(Rational(500000000000), '5e1_1'.to_r)
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(5), Rational('5'))
 | 
			
		||||
    assert_equal(Rational(-5), Rational('-5'))
 | 
			
		||||
    assert_equal(Rational(5,3), Rational('5/3'))
 | 
			
		||||
    assert_equal(Rational(-5,3), Rational('-5/3'))
 | 
			
		||||
    assert_equal(Rational(5,-3), Rational('5/-3'))
 | 
			
		||||
    assert_equal(Rational(-5,-3), Rational('-5/-3'))
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(33,100), Rational('0.33'))
 | 
			
		||||
    assert_equal(Rational(-33,100), Rational('-0.33'))
 | 
			
		||||
    assert_equal(Rational(-33,100), Rational('-0.3_3'))
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,2), Rational('5e-1'))
 | 
			
		||||
    assert_equal(Rational(50), Rational('5e1'))
 | 
			
		||||
    assert_equal(Rational(50), Rational('5E1'))
 | 
			
		||||
    assert_equal(Rational(500), Rational('5e2'))
 | 
			
		||||
    assert_equal(Rational(5000), Rational('5e3'))
 | 
			
		||||
    assert_equal(Rational(500000000000), Rational('5e1_1'))
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(5.0), Rational('5.0'))
 | 
			
		||||
    assert_equal(Rational(-5.0), Rational('-5.0'))
 | 
			
		||||
    assert_equal(Rational(5.0,3), Rational('5.0/3'))
 | 
			
		||||
    assert_equal(Rational(-5.0,3), Rational('-5.0/3'))
 | 
			
		||||
    assert_equal(Rational(5.0,-3), Rational('5.0/-3'))
 | 
			
		||||
    assert_equal(Rational(-5.0,-3), Rational('-5.0/-3'))
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(0), '_'.to_r)
 | 
			
		||||
    assert_equal(Rational(0), '_5'.to_r)
 | 
			
		||||
    assert_equal(Rational(5), '5_'.to_r)
 | 
			
		||||
    assert_equal(Rational(5), '5x'.to_r)
 | 
			
		||||
    assert_equal(Rational(5), '5/_3'.to_r)
 | 
			
		||||
    assert_equal(Rational(5,3), '5/3_'.to_r)
 | 
			
		||||
    assert_equal(Rational(5,3), '5/3.3'.to_r)
 | 
			
		||||
    assert_equal(Rational(5,3), '5/3x'.to_r)
 | 
			
		||||
    assert_raise(ArgumentError){ Rational('')}
 | 
			
		||||
    assert_raise(ArgumentError){ Rational('_')}
 | 
			
		||||
    assert_raise(ArgumentError){ Rational('_5')}
 | 
			
		||||
    assert_raise(ArgumentError){ Rational('5_')}
 | 
			
		||||
    assert_raise(ArgumentError){ Rational('5x')}
 | 
			
		||||
    assert_raise(ArgumentError){ Rational('5/_3')}
 | 
			
		||||
    assert_raise(ArgumentError){ Rational('5/3_')}
 | 
			
		||||
    assert_raise(ArgumentError){ Rational('5/3.3')}
 | 
			
		||||
    assert_raise(ArgumentError){ Rational('5/3x')}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
=begin
 | 
			
		||||
  def test_reciprocal
 | 
			
		||||
    assert_equal(Rational(1,9), Rational(9,1).reciprocal)
 | 
			
		||||
    assert_equal(Rational(9,1), Rational(1,9).reciprocal)
 | 
			
		||||
    assert_equal(Rational(-1,9), Rational(-9,1).reciprocal)
 | 
			
		||||
    assert_equal(Rational(-9,1), Rational(-1,9).reciprocal)
 | 
			
		||||
  end
 | 
			
		||||
=end
 | 
			
		||||
 | 
			
		||||
  def test_to_i
 | 
			
		||||
    assert_equal(1, Rational(3,2).to_i)
 | 
			
		||||
    assert_equal(1, Integer(Rational(3,2)))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_f
 | 
			
		||||
    assert_equal(1.5, Rational(3,2).to_f)
 | 
			
		||||
    assert_equal(1.5, Float(Rational(3,2)))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_c
 | 
			
		||||
    if defined?(Complex) && !Complex.instance_variable_get('@RCS_ID')
 | 
			
		||||
      if defined?(Rational::Unify)
 | 
			
		||||
	assert_equal(Rational(3,2), Rational(3,2).to_c)
 | 
			
		||||
	assert_equal(Rational(3,2), Complex(Rational(3,2)))
 | 
			
		||||
      else
 | 
			
		||||
	assert_equal(Complex(Rational(3,2)), Rational(3,2).to_c)
 | 
			
		||||
	assert_equal(Complex(Rational(3,2)), Complex(Rational(3,2)))
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_r
 | 
			
		||||
    c = nil.to_r
 | 
			
		||||
    assert_equal([0,1] , [c.numerator, c.denominator])
 | 
			
		||||
 | 
			
		||||
    c = 0.to_r
 | 
			
		||||
    assert_equal([0,1] , [c.numerator, c.denominator])
 | 
			
		||||
 | 
			
		||||
    c = 1.to_r
 | 
			
		||||
    assert_equal([1,1] , [c.numerator, c.denominator])
 | 
			
		||||
 | 
			
		||||
    c = 1.1.to_r
 | 
			
		||||
    assert_equal([2476979795053773, 2251799813685248],
 | 
			
		||||
		 [c.numerator, c.denominator])
 | 
			
		||||
 | 
			
		||||
    c = Rational(1,2).to_r
 | 
			
		||||
    assert_equal([1,2] , [c.numerator, c.denominator])
 | 
			
		||||
 | 
			
		||||
    if defined?(Complex)
 | 
			
		||||
      if Complex.instance_variable_get('@RCS_ID')
 | 
			
		||||
	assert_raise(NoMethodError){Complex(1,2).to_r}
 | 
			
		||||
      else
 | 
			
		||||
	assert_raise(RangeError){Complex(1,2).to_r}
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_prec
 | 
			
		||||
    assert_equal(true, Rational < Precision)
 | 
			
		||||
 | 
			
		||||
    c = Rational(3,2)
 | 
			
		||||
 | 
			
		||||
    assert_eql(1, c.prec(Integer))
 | 
			
		||||
    assert_eql(1.5, c.prec(Float))
 | 
			
		||||
    assert_eql(c, c.prec(Rational))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_supp
 | 
			
		||||
    assert_equal(true, 1.scalar?)
 | 
			
		||||
    assert_equal(true, 1.1.scalar?)
 | 
			
		||||
 | 
			
		||||
    if defined?(Complex)
 | 
			
		||||
      assert_equal(1, 1.real)
 | 
			
		||||
      assert_equal(0, 1.image)
 | 
			
		||||
      assert_equal(0, 1.imag)
 | 
			
		||||
 | 
			
		||||
      assert_equal(1.1, 1.1.real)
 | 
			
		||||
      assert_equal(0, 1.1.image)
 | 
			
		||||
      assert_equal(0, 1.1.imag)
 | 
			
		||||
 | 
			
		||||
      assert_equal(0, 1.arg)
 | 
			
		||||
      assert_equal(0, 1.angle)
 | 
			
		||||
 | 
			
		||||
      assert_equal(0, 1.0.arg)
 | 
			
		||||
      assert_equal(0, 1.0.angle)
 | 
			
		||||
 | 
			
		||||
      assert_equal(Math::PI, -1.arg)
 | 
			
		||||
      assert_equal(Math::PI, -1.angle)
 | 
			
		||||
 | 
			
		||||
      assert_equal(Math::PI, -1.0.arg)
 | 
			
		||||
      assert_equal(Math::PI, -1.0.angle)
 | 
			
		||||
 | 
			
		||||
      assert_equal([1,0], 1.polar)
 | 
			
		||||
      assert_equal([1, Math::PI], -1.polar)
 | 
			
		||||
 | 
			
		||||
      assert_equal([1.0,0], 1.0.polar)
 | 
			
		||||
      assert_equal([1.0, Math::PI], -1.0.polar)
 | 
			
		||||
 | 
			
		||||
      assert_equal(1, 1.conjugate)
 | 
			
		||||
      assert_equal(-1, -1.conjugate)
 | 
			
		||||
      assert_equal(1, 1.conj)
 | 
			
		||||
      assert_equal(-1, -1.conj)
 | 
			
		||||
 | 
			
		||||
      assert_equal(1.1, 1.1.conjugate)
 | 
			
		||||
      assert_equal(-1.1, -1.1.conjugate)
 | 
			
		||||
      assert_equal(1.1, 1.1.conj)
 | 
			
		||||
      assert_equal(-1.1, -1.1.conj)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assert_equal(1, 1.numerator)
 | 
			
		||||
    assert_equal(9, 9.numerator)
 | 
			
		||||
    assert_equal(1, 1.denominator)
 | 
			
		||||
    assert_equal(1, 9.denominator)
 | 
			
		||||
 | 
			
		||||
    assert_equal(1.0, 1.0.numerator)
 | 
			
		||||
    assert_equal(9.0, 9.0.numerator)
 | 
			
		||||
    assert_equal(1.0, 1.0.denominator)
 | 
			
		||||
    assert_equal(1.0, 9.0.denominator)
 | 
			
		||||
 | 
			
		||||
=begin
 | 
			
		||||
    assert_equal(Rational(1,9), 9.reciprocal)
 | 
			
		||||
    assert_equal(Rational(1,9), 9.0.reciprocal)
 | 
			
		||||
    assert_equal(Rational(1,9), 9.inverse)
 | 
			
		||||
    assert_equal(Rational(1,9), 9.0.inverse)
 | 
			
		||||
=end
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,2), 1.quo(2))
 | 
			
		||||
    assert_equal(Rational(5000000000), 10000000000.quo(2))
 | 
			
		||||
    assert_equal(0.5, 1.0.quo(2))
 | 
			
		||||
    assert_equal(Rational(1,4), Rational(1,2).quo(2))
 | 
			
		||||
 | 
			
		||||
    assert_equal(Rational(1,2), 1.rdiv(2))
 | 
			
		||||
    assert_equal(Rational(5000000000), 10000000000.rdiv(2))
 | 
			
		||||
    assert_equal(Rational(1,2), 1.0.rdiv(2))
 | 
			
		||||
    assert_equal(Rational(1,4), Rational(1,2).rdiv(2))
 | 
			
		||||
 | 
			
		||||
    assert_equal(0.5, 1.fdiv(2))
 | 
			
		||||
    assert_equal(5000000000.0, 10000000000.fdiv(2))
 | 
			
		||||
    assert_equal(0.5, 1.0.fdiv(2))
 | 
			
		||||
    assert_equal(0.25, Rational(1,2).fdiv(2))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_fixed_bug
 | 
			
		||||
    if defined?(Rational::Unify)
 | 
			
		||||
      assert_instance_of(Fixnum, Rational(1,2) ** 0) # mathn's bug
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
=begin
 | 
			
		||||
  def test_known_bug
 | 
			
		||||
    n = Float::MAX.to_i * 2
 | 
			
		||||
    assert_equal(1.0, Rational(n + 2, n + 1).to_f, '[ruby-dev:33852]')
 | 
			
		||||
  end
 | 
			
		||||
=end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue