Project

General

Profile

Feature #12484 ยป 0002-optimize-Rational-methods.patch

tad (Tadashi Saito), 06/12/2016 12:55 PM

View differences:

rational.c
27 27

  
28 28
#define GMP_GCD_DIGITS 1
29 29

  
30
#define INT_POSITIVE_P(x) (FIXNUM_P(x) ? ((SIGNED_VALUE)(x) > (SIGNED_VALUE)INT2FIX(0)) : BIGNUM_POSITIVE_P(x))
31
#define INT_NEGATIVE_P(x) (FIXNUM_P(x) ? ((SIGNED_VALUE)(x) < 0) : BIGNUM_NEGATIVE_P(x))
32
#define INT_ZERO_P(x) (FIXNUM_P(x) ? (FIX2LONG(x) == 0) : rb_bigzero_p(x))
33

  
30 34
VALUE rb_cRational;
31 35

  
32
static ID id_abs, id_cmp, id_convert, id_eqeq_p, id_expt, id_fdiv,
33
    id_idiv, id_integer_p, id_negate, id_to_f,
34
    id_to_i, id_truncate, id_i_num, id_i_den;
36
static ID id_abs, id_eqeq_p, id_idiv, id_integer_p, id_negate, id_to_i,
37
    id_i_num, id_i_den;
35 38

  
36 39
#define f_boolcast(x) ((x) ? Qtrue : Qfalse)
37 40
#define f_inspect rb_inspect
......
69 72
}
70 73

  
71 74
inline static VALUE
72
f_cmp(VALUE x, VALUE y)
73
{
74
    if (FIXNUM_P(x) && FIXNUM_P(y)) {
75
	long c = FIX2LONG(x) - FIX2LONG(y);
76
	if (c > 0)
77
	    c = 1;
78
	else if (c < 0)
79
	    c = -1;
80
	return INT2FIX(c);
81
    }
82
    return rb_funcall(x, id_cmp, 1, y);
83
}
84

  
85
inline static VALUE
86 75
f_div(VALUE x, VALUE y)
87 76
{
88 77
    if (FIXNUM_P(y) && FIX2LONG(y) == 1)
89 78
	return x;
79
    if (FIXNUM_P(x) || RB_TYPE_P(x, T_BIGNUM))
80
	return rb_int_div(x, y);
90 81
    return rb_funcall(x, '/', 1, y);
91 82
}
92 83

  
......
120 111
	}
121 112
	else if (ix == 1)
122 113
	    return y;
114
	return rb_int_mul(x, y);
123 115
    }
116
    else if (RB_TYPE_P(x, T_BIGNUM))
117
	return rb_int_mul(x, y);
124 118
    return rb_funcall(x, '*', 1, y);
125 119
}
126 120

  
......
132 126
    return rb_funcall(x, '-', 1, y);
133 127
}
134 128

  
135
fun1(abs)
129
inline static VALUE
130
f_abs(VALUE x)
131
{
132
    if (FIXNUM_P(x) || RB_TYPE_P(x, T_BIGNUM))
133
	return rb_int_abs(x);
134
    return rb_funcall(x, id_abs, 0);
135
}
136

  
136 137
fun1(integer_p)
137 138
fun1(negate)
138 139

  
......
143 144
	return rb_str_to_inum(x, 10, 0);
144 145
    return rb_funcall(x, id_to_i, 0);
145 146
}
146
inline static VALUE
147
f_to_f(VALUE x)
148
{
149
    if (RB_TYPE_P(x, T_STRING))
150
	return DBL2NUM(rb_str_to_dbl(x, 0));
151
    return rb_funcall(x, id_to_f, 0);
152
}
153 147

  
154 148
inline static VALUE
155 149
f_eqeq_p(VALUE x, VALUE y)
......
159 153
    return rb_funcall(x, id_eqeq_p, 1, y);
160 154
}
161 155

  
162
fun2(expt)
163
fun2(fdiv)
164 156
fun2(idiv)
165 157

  
166
#define f_expt10(x) f_expt(INT2FIX(10), x)
167

  
168
inline static VALUE
169
f_negative_p(VALUE x)
170
{
171
    if (FIXNUM_P(x))
172
	return f_boolcast(FIX2LONG(x) < 0);
173
    return rb_funcall(x, '<', 1, ZERO);
174
}
175

  
176
#define f_positive_p(x) (!f_negative_p(x))
158
#define f_expt10(x) rb_int_pow(INT2FIX(10), x)
177 159

  
178 160
inline static VALUE
179 161
f_zero_p(VALUE x)
......
327 309
    if (FIXNUM_P(x) && FIXNUM_P(y))
328 310
	return LONG2NUM(i_gcd(FIX2LONG(x), FIX2LONG(y)));
329 311

  
330
    if (f_negative_p(x))
331
	x = f_negate(x);
332
    if (f_negative_p(y))
333
	y = f_negate(y);
312
    if (INT_NEGATIVE_P(x))
313
	x = rb_int_uminus(x);
314
    if (INT_NEGATIVE_P(y))
315
	y = rb_int_uminus(y);
334 316

  
335
    if (f_zero_p(x))
317
    if (INT_ZERO_P(x))
336 318
	return y;
337
    if (f_zero_p(y))
319
    if (INT_ZERO_P(y))
338 320
	return x;
339 321

  
340 322
    for (;;) {
......
345 327
		return LONG2NUM(i_gcd(FIX2LONG(x), FIX2LONG(y)));
346 328
	}
347 329
	z = x;
348
	x = f_mod(y, x);
330
	x = rb_int_modulo(y, x);
349 331
	y = z;
350 332
    }
351 333
    /* NOTREACHED */
......
389 371
inline static VALUE
390 372
f_lcm(VALUE x, VALUE y)
391 373
{
392
    if (f_zero_p(x) || f_zero_p(y))
374
    if (INT_ZERO_P(x) || INT_ZERO_P(y))
393 375
	return ZERO;
394 376
    return f_abs(f_mul(f_div(x, f_gcd(x, y)), y));
395 377
}
......
420 402
    return nurat_s_new_internal(klass, ZERO, ONE);
421 403
}
422 404

  
423
#define rb_raise_zerodiv() rb_raise(rb_eZeroDivError, "divided by 0")
424

  
425 405
#if 0
426 406
static VALUE
427 407
nurat_s_new_bang(int argc, VALUE *argv, VALUE klass)
......
440 420
	if (!k_integer_p(den))
441 421
	    den = f_to_i(den);
442 422

  
443
	switch (FIX2INT(f_cmp(den, ZERO))) {
423
	switch (FIX2INT(rb_int_cmp(den, ZERO))) {
444 424
	  case -1:
445 425
	    num = f_negate(num);
446 426
	    den = f_negate(den);
447 427
	    break;
448 428
	  case 0:
449
	    rb_raise_zerodiv();
429
	    rb_num_zerodiv();
450 430
	    break;
451 431
	}
452 432
	break;
......
499 479
{
500 480
    VALUE gcd;
501 481

  
502
    switch (FIX2INT(f_cmp(den, ZERO))) {
482
    switch (FIX2INT(rb_int_cmp(den, ZERO))) {
503 483
      case -1:
504 484
	num = f_negate(num);
505 485
	den = f_negate(den);
506 486
	break;
507 487
      case 0:
508
	rb_raise_zerodiv();
488
	rb_num_zerodiv();
509 489
	break;
510 490
    }
511 491

  
......
523 503
inline static VALUE
524 504
nurat_s_canonicalize_internal_no_reduce(VALUE klass, VALUE num, VALUE den)
525 505
{
526
    switch (FIX2INT(f_cmp(den, ZERO))) {
506
    switch (FIX2INT(rb_int_cmp(den, ZERO))) {
527 507
      case -1:
528 508
	num = f_negate(num);
529 509
	den = f_negate(den);
530 510
	break;
531 511
      case 0:
532
	rb_raise_zerodiv();
512
	rb_num_zerodiv();
533 513
	break;
534 514
    }
535 515

  
......
575 555
    return nurat_s_canonicalize_internal_no_reduce(klass, x, y);
576 556
}
577 557

  
558
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass);
578 559
/*
579 560
 * call-seq:
580 561
 *    Rational(x[, y])  ->  numeric
......
605 586
static VALUE
606 587
nurat_f_rational(int argc, VALUE *argv, VALUE klass)
607 588
{
608
    return rb_funcall2(rb_cRational, id_convert, argc, argv);
589
    return nurat_s_convert(argc, argv, rb_cRational);
609 590
}
610 591

  
611 592
/*
......
645 626
    return dat->den;
646 627
}
647 628

  
629
/*
630
 * call-seq:
631
 *    -rat  ->  rational
632
 *
633
 * Negates +rat+.
634
 */
635
static VALUE
636
nurat_negate(VALUE self)
637
{
638
    get_dat1(self);
639
    return f_rational_new2(CLASS_OF(self), rb_int_uminus(dat->num), dat->den);
640
}
641

  
648 642
#ifndef NDEBUG
649 643
#define f_imul f_imul_orig
650 644
#endif
......
699 693
	VALUE c;
700 694

  
701 695
	if (k == '+')
702
	    c = f_add(a, b);
696
	    c = rb_int_plus(a, b);
703 697
	else
704
	    c = f_sub(a, b);
698
	    c = rb_int_minus(a, b);
705 699

  
706
	b = f_idiv(aden, g);
700
	b = rb_int_idiv(aden, g);
707 701
	g = f_gcd(c, g);
708
	num = f_idiv(c, g);
709
	a = f_idiv(bden, g);
710
	den = f_mul(a, b);
702
	num = rb_int_idiv(c, g);
703
	a = rb_int_idiv(bden, g);
704
	den = rb_int_mul(a, b);
711 705
    }
712 706
    else {
713 707
	VALUE g = f_gcd(aden, bden);
714
	VALUE a = f_mul(anum, f_idiv(bden, g));
715
	VALUE b = f_mul(bnum, f_idiv(aden, g));
708
	VALUE a = rb_int_mul(anum, rb_int_idiv(bden, g));
709
	VALUE b = rb_int_mul(bnum, rb_int_idiv(aden, g));
716 710
	VALUE c;
717 711

  
718 712
	if (k == '+')
719
	    c = f_add(a, b);
713
	    c = rb_int_plus(a, b);
720 714
	else
721
	    c = f_sub(a, b);
715
	    c = rb_int_minus(a, b);
722 716

  
723
	b = f_idiv(aden, g);
717
	b = rb_int_idiv(aden, g);
724 718
	g = f_gcd(c, g);
725
	num = f_idiv(c, g);
726
	a = f_idiv(bden, g);
727
	den = f_mul(a, b);
719
	num = rb_int_idiv(c, g);
720
	a = rb_int_idiv(bden, g);
721
	den = rb_int_mul(a, b);
728 722
    }
729 723
    return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
730 724
}
731 725

  
726
static VALUE nurat_to_f(VALUE self);
732 727
/*
733 728
 * call-seq:
734 729
 *    rat + numeric  ->  numeric
......
748 743
	{
749 744
	    get_dat1(self);
750 745

  
751
	    return f_addsub(self,
752
			    dat->num, dat->den,
753
			    other, ONE, '+');
746
	    return f_rational_new_no_reduce2(CLASS_OF(self),
747
					     rb_int_plus(dat->num, rb_int_mul(other, dat->den)),
748
					     dat->den);
754 749
	}
755 750
    }
756 751
    else if (RB_TYPE_P(other, T_FLOAT)) {
757
	return f_add(f_to_f(self), other);
752
	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) + RFLOAT_VALUE(other));
758 753
    }
759 754
    else if (RB_TYPE_P(other, T_RATIONAL)) {
760 755
	{
......
789 784
	{
790 785
	    get_dat1(self);
791 786

  
792
	    return f_addsub(self,
793
			    dat->num, dat->den,
794
			    other, ONE, '-');
787
	    return f_rational_new_no_reduce2(CLASS_OF(self),
788
					     rb_int_minus(dat->num, rb_int_mul(other, dat->den)),
789
					     dat->den);
795 790
	}
796 791
    }
797 792
    else if (RB_TYPE_P(other, T_FLOAT)) {
798
	return f_sub(f_to_f(self), other);
793
	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) - RFLOAT_VALUE(other));
799 794
    }
800 795
    else if (RB_TYPE_P(other, T_RATIONAL)) {
801 796
	{
......
819 814
    if (k == '/') {
820 815
	VALUE t;
821 816

  
822
	if (f_negative_p(bnum)) {
823
	    anum = f_negate(anum);
824
	    bnum = f_negate(bnum);
817
	if (INT_NEGATIVE_P(bnum)) {
818
	    anum = rb_int_uminus(anum);
819
	    bnum = rb_int_uminus(bnum);
825 820
	}
826 821
	t = bnum;
827 822
	bnum = bden;
......
844 839
	VALUE g1 = f_gcd(anum, bden);
845 840
	VALUE g2 = f_gcd(aden, bnum);
846 841

  
847
	num = f_mul(f_idiv(anum, g1), f_idiv(bnum, g2));
848
	den = f_mul(f_idiv(aden, g2), f_idiv(bden, g1));
842
	num = rb_int_mul(rb_int_idiv(anum, g1), rb_int_idiv(bnum, g2));
843
	den = rb_int_mul(rb_int_idiv(aden, g2), rb_int_idiv(bden, g1));
849 844
    }
850 845
    return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
851 846
}
......
875 870
	}
876 871
    }
877 872
    else if (RB_TYPE_P(other, T_FLOAT)) {
878
	return f_mul(f_to_f(self), other);
873
	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) * RFLOAT_VALUE(other));
879 874
    }
880 875
    else if (RB_TYPE_P(other, T_RATIONAL)) {
881 876
	{
......
909 904
{
910 905
    if (RB_TYPE_P(other, T_FIXNUM) || RB_TYPE_P(other, T_BIGNUM)) {
911 906
	if (f_zero_p(other))
912
	    rb_raise_zerodiv();
907
	    rb_num_zerodiv();
913 908
	{
914 909
	    get_dat1(self);
915 910

  
......
919 914
	}
920 915
    }
921 916
    else if (RB_TYPE_P(other, T_FLOAT))
922
	return rb_funcall(f_to_f(self), '/', 1, other);
917
	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) / RFLOAT_VALUE(other));
923 918
    else if (RB_TYPE_P(other, T_RATIONAL)) {
924 919
	if (f_zero_p(other))
925
	    rb_raise_zerodiv();
920
	    rb_num_zerodiv();
926 921
	{
927 922
	    get_dat2(self, other);
928 923

  
......
953 948
static VALUE
954 949
nurat_fdiv(VALUE self, VALUE other)
955 950
{
951
    VALUE div;
956 952
    if (f_zero_p(other))
957
	return f_div(self, f_to_f(other));
958
    return f_to_f(f_div(self, other));
953
	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) / 0.0);
954
    if (FIXNUM_P(other) && FIX2LONG(other) == 1)
955
	return nurat_to_f(self);
956
    div = nurat_div(self, other);
957
    if (RB_TYPE_P(div, T_RATIONAL))
958
	return nurat_to_f(div);
959
    if (RB_TYPE_P(div, T_FLOAT))
960
	return div;
961
    return rb_funcall(div, rb_intern("to_f"), 0);
959 962
}
960 963

  
961 964
inline static VALUE
......
1004 1007
		return f_rational_new_bang1(CLASS_OF(self), INT2FIX(f_odd_p(other) ? -1 : 1));
1005 1008
	    }
1006 1009
	    else if (f_zero_p(dat->num)) {
1007
		if (FIX2INT(f_cmp(other, ZERO)) == -1) {
1008
		    rb_raise_zerodiv();
1010
		if (FIX2INT(rb_int_cmp(ZERO, other)) == 1) {
1011
		    rb_num_zerodiv();
1009 1012
		}
1010 1013
		else {
1011 1014
		    return f_rational_new_bang1(CLASS_OF(self), ZERO);
......
1021 1024

  
1022 1025
	    get_dat1(self);
1023 1026

  
1024
	    switch (FIX2INT(f_cmp(other, ZERO))) {
1027
	    switch (FIX2INT(rb_int_cmp(other, ZERO))) {
1025 1028
	      case 1:
1026
		num = f_expt(dat->num, other);
1027
		den = f_expt(dat->den, other);
1029
		num = rb_int_pow(dat->num, other);
1030
		den = rb_int_pow(dat->den, other);
1028 1031
		break;
1029 1032
	      case -1:
1030
		num = f_expt(dat->den, f_negate(other));
1031
		den = f_expt(dat->num, f_negate(other));
1033
		num = rb_int_pow(dat->den, rb_int_uminus(other));
1034
		den = rb_int_pow(dat->num, rb_int_uminus(other));
1032 1035
		break;
1033 1036
	      default:
1034 1037
		num = ONE;
......
1040 1043
    }
1041 1044
    else if (RB_TYPE_P(other, T_BIGNUM)) {
1042 1045
	rb_warn("in a**b, b may be too big");
1043
	return f_expt(f_to_f(self), other);
1046
	return rb_float_pow(nurat_to_f(self), other);
1044 1047
    }
1045 1048
    else if (RB_TYPE_P(other, T_FLOAT) || RB_TYPE_P(other, T_RATIONAL)) {
1046
	return f_expt(f_to_f(self), other);
1049
	return rb_float_pow(nurat_to_f(self), other);
1047 1050
    }
1048 1051
    else {
1049
	return rb_num_coerce_bin(self, other, id_expt);
1052
	return rb_num_coerce_bin(self, other, rb_intern("**"));
1050 1053
    }
1051 1054
}
1052 1055

  
......
1072 1075
	    get_dat1(self);
1073 1076

  
1074 1077
	    if (FIXNUM_P(dat->den) && FIX2LONG(dat->den) == 1)
1075
		return f_cmp(dat->num, other); /* c14n */
1076
	    return f_cmp(self, f_rational_new_bang1(CLASS_OF(self), other));
1078
		return rb_int_cmp(dat->num, other); /* c14n */
1079
	    other = f_rational_new_bang1(CLASS_OF(self), other);
1077 1080
	}
1078 1081
    }
1079
    else if (RB_TYPE_P(other, T_FLOAT)) {
1080
	return f_cmp(f_to_f(self), other);
1082
    if (RB_TYPE_P(other, T_FLOAT)) {
1083
	return rb_dbl_cmp(RFLOAT_VALUE(nurat_to_f(self)), RFLOAT_VALUE(other));
1081 1084
    }
1082 1085
    else if (RB_TYPE_P(other, T_RATIONAL)) {
1083 1086
	{
......
1091 1094
		num2 = f_imul(FIX2LONG(bdat->num), FIX2LONG(adat->den));
1092 1095
	    }
1093 1096
	    else {
1094
		num1 = f_mul(adat->num, bdat->den);
1095
		num2 = f_mul(bdat->num, adat->den);
1097
		num1 = rb_int_mul(adat->num, bdat->den);
1098
		num2 = rb_int_mul(bdat->num, adat->den);
1096 1099
	    }
1097
	    return f_cmp(f_sub(num1, num2), ZERO);
1100
	    return rb_int_cmp(rb_int_minus(num1, num2), ZERO);
1098 1101
	}
1099 1102
    }
1100 1103
    else {
1101
	return rb_num_coerce_cmp(self, other, id_cmp);
1104
	return rb_num_coerce_cmp(self, other, rb_intern("<=>"));
1102 1105
    }
1103 1106
}
1104 1107

  
......
1121 1124
	{
1122 1125
	    get_dat1(self);
1123 1126

  
1124
	    if (f_zero_p(dat->num) && f_zero_p(other))
1127
	    if (INT_ZERO_P(dat->num) && INT_ZERO_P(other))
1125 1128
		return Qtrue;
1126 1129

  
1127 1130
	    if (!FIXNUM_P(dat->den))
1128 1131
		return Qfalse;
1129 1132
	    if (FIX2LONG(dat->den) != 1)
1130 1133
		return Qfalse;
1131
	    if (f_eqeq_p(dat->num, other))
1132
		return Qtrue;
1133
	    return Qfalse;
1134
	    return rb_int_equal(dat->num, other);
1134 1135
	}
1135 1136
    }
1136 1137
    else if (RB_TYPE_P(other, T_FLOAT)) {
1137
	return f_eqeq_p(f_to_f(self), other);
1138
	return f_boolcast(rb_dbl_cmp(RFLOAT_VALUE(nurat_to_f(self)), RFLOAT_VALUE(other))
1139
			  == INT2FIX(0));
1138 1140
    }
1139 1141
    else if (RB_TYPE_P(other, T_RATIONAL)) {
1140 1142
	{
1141 1143
	    get_dat2(self, other);
1142 1144

  
1143
	    if (f_zero_p(adat->num) && f_zero_p(bdat->num))
1145
	    if (INT_ZERO_P(adat->num) && INT_ZERO_P(bdat->num))
1144 1146
		return Qtrue;
1145 1147

  
1146
	    return f_boolcast(f_eqeq_p(adat->num, bdat->num) &&
1147
			      f_eqeq_p(adat->den, bdat->den));
1148
	    return f_boolcast(rb_int_equal(adat->num, bdat->num) &&
1149
			      rb_int_equal(adat->den, bdat->den));
1148 1150
	}
1149 1151
    }
1150 1152
    else {
......
1160 1162
	return rb_assoc_new(f_rational_new_bang1(CLASS_OF(self), other), self);
1161 1163
    }
1162 1164
    else if (RB_TYPE_P(other, T_FLOAT)) {
1163
	return rb_assoc_new(other, f_to_f(self));
1165
	return rb_assoc_new(other, nurat_to_f(self));
1164 1166
    }
1165 1167
    else if (RB_TYPE_P(other, T_RATIONAL)) {
1166 1168
	return rb_assoc_new(other, self);
......
1211 1213
}
1212 1214
#endif
1213 1215

  
1216
/*
1217
 *  call-seq:
1218
 *     rat.positive? ->  true or false
1219
 *
1220
 *  Returns +true+ if +rat+ is greater than 0.
1221
 */
1222
static VALUE
1223
nurat_positive_p(VALUE self)
1224
{
1225
    get_dat1(self);
1226
    return f_boolcast(INT_POSITIVE_P(dat->num));
1227
}
1228

  
1229
/*
1230
 *  call-seq:
1231
 *     rat.negative? ->  true or false
1232
 *
1233
 *  Returns +true+ if +rat+ is less than 0.
1234
 */
1235
static VALUE
1236
nurat_negative_p(VALUE self)
1237
{
1238
    get_dat1(self);
1239
    return f_boolcast(INT_NEGATIVE_P(dat->num));
1240
}
1241

  
1214 1242
static VALUE
1215 1243
nurat_floor(VALUE self)
1216 1244
{
1217 1245
    get_dat1(self);
1218
    return f_idiv(dat->num, dat->den);
1246
    return rb_int_idiv(dat->num, dat->den);
1219 1247
}
1220 1248

  
1221 1249
static VALUE
1222 1250
nurat_ceil(VALUE self)
1223 1251
{
1224 1252
    get_dat1(self);
1225
    return f_negate(f_idiv(f_negate(dat->num), dat->den));
1253
    return rb_int_uminus(rb_int_idiv(rb_int_uminus(dat->num), dat->den));
1226 1254
}
1227 1255

  
1228 1256
/*
......
1244 1272
nurat_truncate(VALUE self)
1245 1273
{
1246 1274
    get_dat1(self);
1247
    if (f_negative_p(dat->num))
1248
	return f_negate(f_idiv(f_negate(dat->num), dat->den));
1249
    return f_idiv(dat->num, dat->den);
1275
    if (INT_NEGATIVE_P(dat->num))
1276
	return rb_int_uminus(rb_int_idiv(rb_int_uminus(dat->num), dat->den));
1277
    return rb_int_idiv(dat->num, dat->den);
1250 1278
}
1251 1279

  
1252 1280
static VALUE
......
1258 1286

  
1259 1287
    num = dat->num;
1260 1288
    den = dat->den;
1261
    neg = f_negative_p(num);
1289
    neg = INT_NEGATIVE_P(num);
1262 1290

  
1263 1291
    if (neg)
1264
	num = f_negate(num);
1292
	num = rb_int_uminus(num);
1265 1293

  
1266
    num = f_add(f_mul(num, TWO), den);
1267
    den = f_mul(den, TWO);
1268
    num = f_idiv(num, den);
1294
    num = rb_int_plus(rb_int_mul(num, TWO), den);
1295
    den = rb_int_mul(den, TWO);
1296
    num = rb_int_idiv(num, den);
1269 1297

  
1270 1298
    if (neg)
1271
	num = f_negate(num);
1299
	num = rb_int_uminus(num);
1272 1300

  
1273 1301
    return num;
1274 1302
}
......
1287 1315
	rb_raise(rb_eTypeError, "not an integer");
1288 1316

  
1289 1317
    b = f_expt10(n);
1290
    s = f_mul(self, b);
1318
    s = nurat_mul(self, b);
1291 1319

  
1292 1320
    if (k_float_p(s)) {
1293
	if (f_lt_p(n, ZERO))
1321
	if (INT_NEGATIVE_P(n))
1294 1322
	    return ZERO;
1295 1323
	return self;
1296 1324
    }
......
1301 1329

  
1302 1330
    s = (*func)(s);
1303 1331

  
1304
    s = f_div(f_rational_new_bang1(CLASS_OF(self), s), b);
1332
    s = nurat_div(f_rational_new_bang1(CLASS_OF(self), s), b);
1305 1333

  
1306
    if (f_lt_p(n, ONE))
1307
	s = f_to_i(s);
1334
    if (RB_TYPE_P(s, T_RATIONAL) && FIX2INT(rb_int_cmp(n, ONE)) < 0)
1335
	s = nurat_truncate(s);
1308 1336

  
1309 1337
    return s;
1310 1338
}
......
1421 1449
nurat_to_f(VALUE self)
1422 1450
{
1423 1451
    get_dat1(self);
1424
    return f_fdiv(dat->num, dat->den);
1452
    return rb_int_fdiv(dat->num, dat->den);
1425 1453
}
1426 1454

  
1427 1455
/*
......
1557 1585
    if (argc == 0)
1558 1586
	return self;
1559 1587

  
1560
    if (f_negative_p(self))
1561
	return f_negate(nurat_rationalize(argc, argv, f_abs(self)));
1588
    if (nurat_negative_p(self))
1589
	return nurat_negate(nurat_rationalize(argc, argv, nurat_negate(self)));
1562 1590

  
1563 1591
    rb_scan_args(argc, argv, "01", &e);
1564 1592
    e = f_abs(e);
......
1681 1709
    if (RARRAY_LEN(a) != 2)
1682 1710
	rb_raise(rb_eArgError, "marshaled rational must have an array whose length is 2 but %ld", RARRAY_LEN(a));
1683 1711
    if (f_zero_p(RARRAY_AREF(a, 1)))
1684
	rb_raise_zerodiv();
1712
	rb_num_zerodiv();
1685 1713

  
1686 1714
    rb_ivar_set(self, id_i_num, RARRAY_AREF(a, 0));
1687 1715
    rb_ivar_set(self, id_i_den, RARRAY_AREF(a, 1));
......
1763 1791
    return nurat_s_canonicalize_internal(rb_cRational, x, y);
1764 1792
}
1765 1793

  
1766
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass);
1767

  
1768 1794
VALUE
1769 1795
rb_Rational(VALUE x, VALUE y)
1770 1796
{
......
1832 1858
numeric_quo(VALUE x, VALUE y)
1833 1859
{
1834 1860
    if (RB_TYPE_P(y, T_FLOAT)) {
1835
        return f_fdiv(x, y);
1861
        return rb_funcall(x, rb_intern("fdiv"), 1, y);
1836 1862
    }
1837 1863

  
1838 1864
#ifdef CANON
......
1844 1870
    {
1845 1871
        x = rb_convert_type(x, T_RATIONAL, "Rational", "to_r");
1846 1872
    }
1847
    return rb_funcall(x, '/', 1, y);
1873
    return nurat_div(x, y);
1848 1874
}
1849 1875

  
1850 1876

  
......
1872 1898
    return INT2FIX(1);
1873 1899
}
1874 1900

  
1901
static VALUE float_to_r(VALUE self);
1875 1902
/*
1876 1903
 * call-seq:
1877 1904
 *    flo.numerator  ->  integer
......
1888 1915
    double d = RFLOAT_VALUE(self);
1889 1916
    if (isinf(d) || isnan(d))
1890 1917
	return self;
1891
    return rb_call_super(0, 0);
1918
    return nurat_numerator(float_to_r(self));
1892 1919
}
1893 1920

  
1894 1921
/*
......
1906 1933
    double d = RFLOAT_VALUE(self);
1907 1934
    if (isinf(d) || isnan(d))
1908 1935
	return INT2FIX(1);
1909
    return rb_call_super(0, 0);
1936
    return nurat_denominator(float_to_r(self));
1910 1937
}
1911 1938

  
1912 1939
/*
......
1988 2015
}
1989 2016
#endif
1990 2017

  
1991
#define id_lshift rb_intern("<<")
1992
#define f_lshift(x,n) rb_funcall((x), id_lshift, 1, (n))
1993

  
1994 2018
/*
1995 2019
 * call-seq:
1996 2020
 *    flt.to_r  ->  rational
......
2018 2042
	long ln = FIX2LONG(n);
2019 2043

  
2020 2044
	if (ln == 0)
2021
	    return f_to_r(f);
2045
	    return rb_rational_new1(f);
2022 2046
	if (ln > 0)
2023
	    return f_to_r(f_lshift(f, n));
2047
	    return rb_rational_new1(rb_int_lshift(f, n));
2024 2048
	ln = -ln;
2025
	return rb_rational_new2(f, f_lshift(ONE, INT2FIX(ln)));
2049
	return rb_rational_new2(f, rb_int_lshift(ONE, INT2FIX(ln)));
2026 2050
    }
2027 2051
#else
2028
    return f_to_r(f_mul(f, f_expt(INT2FIX(FLT_RADIX), n)));
2052
    f = rb_int_mul(f, rb_int_pow(INT2FIX(FLT_RADIX), n));
2053
    if (RB_TYPE_P(f, T_RATIONAL))
2054
	return f;
2055
    return rb_rational_new1(f);
2029 2056
#endif
2030 2057
}
2031 2058

  
......
2039 2066
    b = f_add(flt, e);
2040 2067

  
2041 2068
    if (f_eqeq_p(a, b))
2042
        return f_to_r(flt);
2069
        return float_to_r(flt);
2043 2070

  
2044 2071
    nurat_rationalize_internal(a, b, &p, &q);
2045 2072
    return rb_rational_new2(p, q);
......
2051 2078
    VALUE a, b, f, n, p, q;
2052 2079

  
2053 2080
    float_decode_internal(flt, &f, &n);
2054
    if (f_zero_p(f) || f_positive_p(n))
2055
        return rb_rational_new1(f_lshift(f, n));
2081
    if (INT_ZERO_P(f) || FIX2INT(n) >= 0)
2082
        return rb_rational_new1(rb_int_lshift(f, n));
2056 2083

  
2057 2084
#if FLT_RADIX == 2
2058 2085
    {
2059 2086
        VALUE two_times_f, den;
2060 2087

  
2061
        two_times_f = f_mul(TWO, f);
2062
        den = f_lshift(ONE, f_sub(ONE, n));
2088
        two_times_f = rb_int_mul(TWO, f);
2089
        den = rb_int_lshift(ONE, rb_int_minus(ONE, n));
2063 2090

  
2064
        a = rb_rational_new2(f_sub(two_times_f, ONE), den);
2065
        b = rb_rational_new2(f_add(two_times_f, ONE), den);
2091
        a = rb_rational_new2(rb_int_minus(two_times_f, ONE), den);
2092
        b = rb_rational_new2(rb_int_plus(two_times_f, ONE), den);
2066 2093
    }
2067 2094
#else
2068 2095
    {
2069 2096
        VALUE radix_times_f, den;
2070 2097

  
2071
        radix_times_f = f_mul(INT2FIX(FLT_RADIX), f);
2072
        den = f_expt(INT2FIX(FLT_RADIX), f_sub(ONE, n));
2098
        radix_times_f = rb_int_mul(INT2FIX(FLT_RADIX), f);
2099
        den = rb_int_pow(INT2FIX(FLT_RADIX), rb_int_minus(ONE, n));
2073 2100

  
2074
        a = rb_rational_new2(f_sub(radix_times_f, INT2FIX(FLT_RADIX - 1)), den);
2075
        b = rb_rational_new2(f_add(radix_times_f, INT2FIX(FLT_RADIX - 1)), den);
2101
        a = rb_rational_new2(rb_int_minus(radix_times_f, INT2FIX(FLT_RADIX - 1)), den);
2102
        b = rb_rational_new2(rb_int_plus(radix_times_f, INT2FIX(FLT_RADIX - 1)), den);
2076 2103
    }
2077 2104
#endif
2078 2105

  
2079
    if (f_eqeq_p(a, b))
2080
        return f_to_r(flt);
2106
    if (nurat_eqeq_p(a, b))
2107
        return float_to_r(flt);
2081 2108

  
2082 2109
    nurat_rationalize_internal(a, b, &p, &q);
2083 2110
    return rb_rational_new2(p, q);
......
2101 2128
float_rationalize(int argc, VALUE *argv, VALUE self)
2102 2129
{
2103 2130
    VALUE e;
2131
    double d = RFLOAT_VALUE(self);
2104 2132

  
2105
    if (f_negative_p(self))
2106
        return f_negate(float_rationalize(argc, argv, f_abs(self)));
2133
    if (d < 0.0)
2134
        return nurat_negate(float_rationalize(argc, argv, DBL2NUM(-d)));
2107 2135

  
2108 2136
    rb_scan_args(argc, argv, "01", &e);
2109 2137

  
......
2214 2242
	    return 0;
2215 2243
	{
2216 2244
	    VALUE l = f_expt10(INT2NUM(count));
2217
	    *num = f_mul(*num, l);
2218
	    *num = f_add(*num, fp);
2219
	    *num = f_div(*num, l);
2245
#ifdef CANON
2246
	    if (canonicalization) {
2247
		*num = rb_int_mul(*num, l);
2248
		*num = rb_int_plus(*num, fp);
2249
		*num = rb_rational_new2(*num, l);
2250
	    }
2251
	    else
2252
#endif
2253
	    {
2254
		*num = nurat_mul(*num, l);
2255
		*num = rb_rational_plus(*num, fp);
2256
		*num = nurat_div(*num, l);
2257
	    }
2220 2258
	}
2221 2259
    }
2222 2260

  
......
2228 2266
	if (!read_digits(s, strict, &exp, NULL))
2229 2267
	    return 0;
2230 2268
	if (expsign == '-')
2231
	    exp = f_negate(exp);
2269
	    exp = rb_int_uminus(exp);
2232 2270
    }
2233 2271

  
2234 2272
    if (numsign == '-')
2235
	*num = f_negate(*num);
2273
	*num = nurat_negate(*num);
2236 2274
    if (!NIL_P(exp)) {
2237 2275
	VALUE l = f_expt10(exp);
2238
	*num = f_mul(*num, l);
2276
	*num = nurat_mul(*num, l);
2239 2277
    }
2240 2278
    return 1;
2241 2279
}
......
2262 2300
	if (!read_den(s, strict, &den))
2263 2301
	    return 0;
2264 2302
	if (!(FIXNUM_P(den) && FIX2LONG(den) == 1))
2265
	    *num = f_div(*num, den);
2303
	    *num = nurat_div(*num, den);
2266 2304
    }
2267 2305
    return 1;
2268 2306
}
......
2418 2456
    rb_match_busy(backref);
2419 2457

  
2420 2458
    if (RB_TYPE_P(a1, T_FLOAT)) {
2421
	a1 = f_to_r(a1);
2459
	a1 = float_to_r(a1);
2422 2460
    }
2423 2461
    else if (RB_TYPE_P(a1, T_STRING)) {
2424 2462
	a1 = string_to_r_strict(a1);
2425 2463
    }
2426 2464

  
2427 2465
    if (RB_TYPE_P(a2, T_FLOAT)) {
2428
	a2 = f_to_r(a2);
2466
	a2 = float_to_r(a2);
2429 2467
    }
2430 2468
    else if (RB_TYPE_P(a2, T_STRING)) {
2431 2469
	a2 = string_to_r_strict(a2);
......
2507 2545
    assert(fprintf(stderr, "assert() is now active\n"));
2508 2546

  
2509 2547
    id_abs = rb_intern("abs");
2510
    id_cmp = rb_intern("<=>");
2511
    id_convert = rb_intern("convert");
2512 2548
    id_eqeq_p = rb_intern("==");
2513
    id_expt = rb_intern("**");
2514
    id_fdiv = rb_intern("fdiv");
2515 2549
    id_idiv = rb_intern("div");
2516 2550
    id_integer_p = rb_intern("integer?");
2517 2551
    id_negate = rb_intern("-@");
2518
    id_to_f = rb_intern("to_f");
2519 2552
    id_to_i = rb_intern("to_i");
2520
    id_truncate = rb_intern("truncate");
2521 2553
    id_i_num = rb_intern("@numerator");
2522 2554
    id_i_den = rb_intern("@denominator");
2523 2555

  
......
2538 2570
    rb_define_method(rb_cRational, "numerator", nurat_numerator, 0);
2539 2571
    rb_define_method(rb_cRational, "denominator", nurat_denominator, 0);
2540 2572

  
2573
    rb_define_method(rb_cRational, "-@", nurat_negate, 0);
2541 2574
    rb_define_method(rb_cRational, "+", rb_rational_plus, 1);
2542 2575
    rb_define_method(rb_cRational, "-", nurat_sub, 1);
2543 2576
    rb_define_method(rb_cRational, "*", nurat_mul, 1);
......
2559 2592
    rb_define_method(rb_cRational, "rational?", nurat_true, 0);
2560 2593
    rb_define_method(rb_cRational, "exact?", nurat_true, 0);
2561 2594
#endif
2595
    rb_define_method(rb_cRational, "positive?", nurat_positive_p, 0);
2596
    rb_define_method(rb_cRational, "negative?", nurat_negative_p, 0);
2562 2597

  
2563 2598
    rb_define_method(rb_cRational, "floor", nurat_floor_n, -1);
2564 2599
    rb_define_method(rb_cRational, "ceil", nurat_ceil_n, -1);
2565
-