104 |
} |
} |
105 |
|
|
106 |
object |
object |
107 |
make_ratio(object num, object den) |
make_ratio(object num, object den,int pre_cancelled) |
108 |
{ |
{ |
109 |
object g, r, integer_divide1(object x, object y), get_gcd(object x, object y); |
object g, r, integer_divide1(object x, object y), get_gcd(object x, object y); |
110 |
vs_mark; |
vs_mark; |
111 |
|
|
112 |
if (number_zerop(den)) |
if (den==small_fixnum(0) /* number_zerop(den) */) |
113 |
FEerror("Zero denominator.", 0); |
FEerror("Zero denominator.", 0); |
114 |
if (number_zerop(num)) |
if (num==small_fixnum(0)/* number_zerop(num) */) |
|
return(small_fixnum(0)); |
|
|
if (type_of(den) == t_fixnum && fix(den) == 1) |
|
115 |
return(num); |
return(num); |
116 |
if (number_minusp(den)) { |
if (number_minusp(den)) { |
117 |
num = number_negate(num); |
num = number_negate(num); |
119 |
den = number_negate(den); |
den = number_negate(den); |
120 |
vs_push(den); |
vs_push(den); |
121 |
} |
} |
122 |
g = get_gcd(num, den); |
if (den==small_fixnum(1)/* type_of(den) == t_fixnum && fix(den) == 1 */) |
|
vs_push(g); |
|
|
num = integer_divide1(num, g); |
|
|
vs_push(num); |
|
|
den = integer_divide1(den, g); |
|
|
vs_push(den); |
|
|
if(type_of(den) == t_fixnum && fix(den) == 1) { |
|
|
vs_reset; |
|
|
return(num); |
|
|
} |
|
|
if(type_of(den) == t_fixnum && fix(den) == -1) { |
|
|
num = number_negate(num); |
|
|
vs_reset; |
|
123 |
return(num); |
return(num); |
124 |
|
if (!pre_cancelled) { |
125 |
|
g = get_gcd(num, den); |
126 |
|
vs_push(g); |
127 |
|
num = integer_divide1(num, g); /*FIXME exact division here*/ |
128 |
|
vs_push(num); |
129 |
|
den = integer_divide1(den, g); |
130 |
|
vs_push(den); |
131 |
|
if(den==small_fixnum(1)/* type_of(den) == t_fixnum && fix(den) == 1 */) { |
132 |
|
vs_reset; |
133 |
|
return(num); |
134 |
|
} |
135 |
|
/* Impossible, as gcd is positive, and den is made positive above. */ |
136 |
|
/* if(type_of(den) == t_fixnum && fix(den) == -1) { */ |
137 |
|
/* num = number_negate(num); */ |
138 |
|
/* vs_reset; */ |
139 |
|
/* return(num); */ |
140 |
|
/* } */ |
141 |
} |
} |
142 |
r = alloc_object(t_ratio); |
r = alloc_object(t_ratio); |
143 |
r->rat.rat_num = num; |
r->rat.rat_num = num; |