## Feature #2561 ยป ruby-1.8.7-rational.patch

View differences:

lib/rational.rb
7 7
`#`
8 8
`# Documentation by Kevin Jackson and Gavin Sinclair.`
9 9
`# `
10
`# Performance improvements by Kurt Stephens.`
11
`#`
10 12
`# When you <tt>require 'rational'</tt>, all interactions between numbers`
11 13
`# potentially return a rational result.  For example:`
12 14
`#`
......
104 106
`      num = -num`
105 107
`      den = -den`
106 108
`    end`
107
`    if num.kind_of?(Integer) and den.kind_of?(Integer)`
108
`      @numerator = num`
109
`      @denominator = den`
110
`    else`
111
`      @numerator = num.to_i`
112
`      @denominator = den.to_i`
113
`    end`
109
`    @numerator = num.to_i`
110
`    @denominator = den.to_i`
114 111
`  end`
115 112

116 113
`  #`
......
122 119
`  #   r + 0.5                # -> 1.25`
123 120
`  #`
124 121
`  def + (a)`
125
`    if a.kind_of?(Rational)`
126
`      num = @numerator * a.denominator`
127
`      num_a = a.numerator * @denominator`
128
`      Rational(num + num_a, @denominator * a.denominator)`
129
`    elsif a.kind_of?(Integer)`
130
`      self + Rational.new!(a, 1)`
131
`    elsif a.kind_of?(Float)`
122
`    case a`
123
`    when Rational`
124
`      Rational((@numerator * a.denominator) + (a.numerator * @denominator), @denominator * a.denominator)`
125
`    when Integer`
126
`      Rational((@numerator                ) + (a           * @denominator), @denominator)`
127
`    when Float`
132 128
`      Float(self) + a`
133 129
`    else`
134 130
`      x, y = a.coerce(self)`
......
146 142
`  #   r - 0.5              # -> 0.25`
147 143
`  #`
148 144
`  def - (a)`
149
`    if a.kind_of?(Rational)`
150
`      num = @numerator * a.denominator`
151
`      num_a = a.numerator * @denominator`
152
`      Rational(num - num_a, @denominator*a.denominator)`
153
`    elsif a.kind_of?(Integer)`
154
`      self - Rational.new!(a, 1)`
155
`    elsif a.kind_of?(Float)`
145
`    case a`
146
`    when Rational`
147
`      Rational((@numerator * a.denominator) - (a.numerator * @denominator), @denominator * a.denominator)`
148
`    when Integer`
149
`      Rational((@numerator                ) - (a           * @denominator), @denominator)`
150
`    when Float`
156 151
`      Float(self) - a`
157 152
`    else`
158 153
`      x, y = a.coerce(self)`
......
161 156
`  end`
162 157

163 158
`  #`
159
`  # Unary Minus--Returns the receiver's value, negated.`
160
`  #`
161
`  def -@`
162
`    Rational.new!(- @numerator, @denominator)`
163
`  end`
164

165
`  #`
164 166
`  # Returns the product of this value and +a+.`
165 167
`  #`
166 168
`  # Examples:`
......
171 173
`  #   r * Rational(1,2)    # -> Rational(3,8)`
172 174
`  #`
173 175
`  def * (a)`
174
`    if a.kind_of?(Rational)`
175
`      num = @numerator * a.numerator`
176
`      den = @denominator * a.denominator`
177
`      Rational(num, den)`
178
`    elsif a.kind_of?(Integer)`
179
`      self * Rational.new!(a, 1)`
180
`    elsif a.kind_of?(Float)`
176
`    case a`
177
`    when Rational`
178
`      Rational(@numerator * a.numerator, @denominator * a.denominator)`
179
`    when Integer`
180
`      Rational(@numerator * a          , @denominator)`
181
`    when Float`
181 182
`      Float(self) * a`
182 183
`    else`
183 184
`      x, y = a.coerce(self)`
......
193 194
`  #   r / Rational(1,2)    # -> Rational(3,2)`
194 195
`  #`
195 196
`  def / (a)`
196
`    if a.kind_of?(Rational)`
197
`      num = @numerator * a.denominator`
198
`      den = @denominator * a.numerator`
199
`      Rational(num, den)`
200
`    elsif a.kind_of?(Integer)`
197
`    case a`
198
`    when Rational`
199
`      Rational(@numerator * a.denominator, @denominator * a.numerator)`
200
`    when Integer`
201 201
`      raise ZeroDivisionError, "division by zero" if a == 0`
202
`      self / Rational.new!(a, 1)`
203
`    elsif a.kind_of?(Float)`
202
`      Rational(@numerator                , @denominator * a          )`
203
`    when Float`
204 204
`      Float(self) / a`
205 205
`    else`
206 206
`      x, y = a.coerce(self)`
......
218 218
`  #   r ** Rational(1,2)   # -> 0.866025403784439`
219 219
`  #`
220 220
`  def ** (other)`
221
`    if other.kind_of?(Rational)`
221
`    case other`
222
`    when Rational, Float`
222 223
`      Float(self) ** other`
223
`    elsif other.kind_of?(Integer)`
224
`    when Integer`
224 225
`      if other > 0`
225
`	num = @numerator ** other`
226
`	den = @denominator ** other`
226
`	Rational.new!(@numerator ** other, @denominator ** other)`
227 227
`      elsif other < 0`
228
`	num = @denominator ** -other`
229
`	den = @numerator ** -other`
230
`      elsif other == 0`
231
`	num = 1`
232
`	den = 1`
228
`	Rational.new!(@denominator ** -other, @numerator ** -other)`
229
`      else`
230
`	Rational.new!(1, 1) # why not Fixnum 1?`
233 231
`      end`
234
`      Rational.new!(num, den)`
235
`    elsif other.kind_of?(Float)`
236
`      Float(self) ** other`
237 232
`    else`
238 233
`      x, y = other.coerce(self)`
239 234
`      x ** y`
......
256 251
`  #`
257 252
`  def % (other)`
258 253
`    value = (self / other).floor`
259
`    return self - other * value`
254
`    self - other * value`
260 255
`  end`
261 256

262 257
`  #`
......
268 263
`  #`
269 264
`  def divmod(other)`
270 265
`    value = (self / other).floor`
271
`    return value, self - other * value`
266
`    [ value, self - other * value ]`
272 267
`  end`
273 268

274 269
`  #`
......
282 277
`    end`
283 278
`  end`
284 279

280
`  # Returns true or false.`
281
`  def zero?`
282
`    @numerator.zero?`
283
`  end`
284

285
`  # See Numeric#nonzero?`
286
`  def nonzero?`
287
`    @numerator.nonzero? ? self : nil`
288
`  end`
289

290

285 291
`  #`
286 292
`  # Returns +true+ iff this value is numerically equal to +other+.`
287 293
`  #`
......
292 298
`  # Don't use Rational.new!`
293 299
`  #`
294 300
`  def == (other)`
295
`    if other.kind_of?(Rational)`
301
`    case other`
302
`    when Rational`
296 303
`      @numerator == other.numerator and @denominator == other.denominator`
297
`    elsif other.kind_of?(Integer)`
298
`      self == Rational.new!(other, 1)`
299
`    elsif other.kind_of?(Float)`
304
`    when Integer`
305
`      @numerator == other && @denominator == 1`
306
`    when Float`
300 307
`      Float(self) == other`
301 308
`    else`
302 309
`      other == self`
......
307 314
`  # Standard comparison operator.`
308 315
`  #`
309 316
`  def <=> (other)`
310
`    if other.kind_of?(Rational)`
311
`      num = @numerator * other.denominator`
312
`      num_a = other.numerator * @denominator`
313
`      v = num - num_a`
314
`      if v > 0`
315
`	return 1`
316
`      elsif v < 0`
317
`	return  -1`
318
`      else`
319
`	return 0`
320
`      end`
321
`    elsif other.kind_of?(Integer)`
322
`      return self <=> Rational.new!(other, 1)`
323
`    elsif other.kind_of?(Float)`
324
`      return Float(self) <=> other`
325
`    elsif defined? other.coerce`
326
`      x, y = other.coerce(self)`
327
`      return x <=> y`
317
`    case other`
318
`    when Rational`
319
`      ((@numerator * other.denominator) <=> (other.numerator * @denominator))`
320
`    when Integer`
321
`      ((@numerator                    ) <=> (other           * @denominator))`
322
`    when Float`
323
`      Float(self) <=> other`
328 324
`    else`
329
`      return nil`
325
`      if defined? other.coerce`
326
`        x, y = other.coerce(self)`
327
`        x <=> y`
328
`      end # nil`
330 329
`    end`
331 330
`  end`
332 331

333 332
`  def coerce(other)`
334
`    if other.kind_of?(Float)`
335
`      return other, self.to_f`
336
`    elsif other.kind_of?(Integer)`
337
`      return Rational.new!(other, 1), self`
333
`    case other`
334
`    when Float`
335
`      [ other, self.to_f ]`
336
`    when Integer`
337
`      [ Rational.new!(other, 1), self ]`
338 338
`    else`
339 339
`      super`
340 340
`    end`
......
363 363

364 364
`  def truncate()`
365 365
`    if @numerator < 0`
366
`      return -((-@numerator).div(@denominator))`
366
`      -((-@numerator).div(@denominator))`
367
`    else`
368
`      @numerator.div(@denominator)`
367 369
`    end`
368
`    @numerator.div(@denominator)`
369 370
`  end`
370 371

371 372
`  alias_method :to_i, :truncate`
372 373

373 374
`  def round()`
374 375
`    if @numerator < 0`
375
`      num = -@numerator`
376
`      num = num * 2 + @denominator`
377
`      den = @denominator * 2`
378
`      -(num.div(den))`
376
`      -((@numerator * -2 + @denominator).div(@denominator * 2))`
379 377
`    else`
380
`      num = @numerator * 2 + @denominator`
381
`      den = @denominator * 2`
382
`      num.div(den)`
378
`      ((@numerator * 2 + @denominator).div(@denominator * 2))`
383 379
`    end`
384 380
`  end`
385 381

......
401 397
`    if @denominator == 1`
402 398
`      @numerator.to_s`
403 399
`    else`
404
`      @numerator.to_s+"/"+@denominator.to_s`
400
`      "#{@numerator}/#{@denominator}"`
405 401
`    end`
406 402
`  end`
407 403

......
418 414
`  #   Rational(5,8).inspect     # -> "Rational(5, 8)"`
419 415
`  #`
420 416
`  def inspect`
421
`    sprintf("Rational(%s, %s)", @numerator.inspect, @denominator.inspect)`
417
`    "Rational(#{@numerator.inspect}, #{@denominator.inspect})"`
422 418
`  end`
423 419

424 420
`  #`
numeric.c
3022 3022
`    return Qtrue;`
3023 3023
`}`
3024 3024

3025
`static VALUE`
3026
`fix_gcd(int argc, VALUE *argv, VALUE self) {`
3027
`  if ( argc != 1 ) {`
3028
`    rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 1);`
3029
`  }`
3030
`  /* Handle Fixnum#gcd(Fixnum) here. */`
3031
`  if ( FIXNUM_P(argv[0]) ) {`
3032
`    /* fprintf(stderr, "Using Fixnum#gcd(Fixnum)\n"); */`
3033
`    long a = FIX2LONG(self);`
3034
`    long b = FIX2LONG(argv[0]);`
3035
`    long min = a < 0 ? - a : a;`
3036
`    long max = b < 0 ? - b : b;`
3037
`    while ( min > 0 ) {`
3038
`      int tmp = min;`
3039
`      min = max % min;`
3040
`      max = tmp;`
3041
`    }`
3042
`    return LONG2FIX(max);`
3043
`  } else {`
3044
`    /* Delegate to Integer#gcd. */`
3045
`    return rb_call_super(1, argv);`
3046
`  }`
3047
`}`
3048

3025 3049
`void`
3026 3050
`Init_Numeric()`
3027 3051
`{`
......
3115 3139
`    rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1);`
3116 3140
`    rb_define_method(rb_cFixnum, "quo", fix_quo, 1);`
3117 3141
`    rb_define_method(rb_cFixnum, "fdiv", fix_quo, 1);`
3142
`    rb_define_method(rb_cFixnum, "gcd", fix_gcd, -1);`
3118 3143
`    rb_define_method(rb_cFixnum, "**", fix_pow, 1);`
3119 3144

3120 3145
`    rb_define_method(rb_cFixnum, "abs", fix_abs, 0);`