Project

General

Profile

Feature #5321 ยป numeric-exact-5321.patch

jeremyevans0 (Jeremy Evans), 08/01/2019 12:57 AM

View differences:

complex.c
34 34

  
35 35
static ID id_abs, id_arg,
36 36
    id_denominator, id_fdiv, id_numerator, id_quo,
37
    id_real_p, id_i_real, id_i_imag,
37
    id_real_p, id_i_real, id_i_imag, id_exact_p,
38 38
    id_finite_p, id_infinite_p, id_rationalize,
39 39
    id_PI;
40 40
#define id_to_i idTo_i
......
1393 1393

  
1394 1394
#define FINITE_TYPE_P(v) (RB_INTEGER_TYPE_P(v) || RB_TYPE_P(v, T_RATIONAL))
1395 1395

  
1396
/*
1397
 * call-seq:
1398
 *    cmp.exact?  ->  true or false
1399
 *
1400
 * Returns +true+ if +cmp+'s real and imaginary parts are both exact numbers,
1401
 * otherwise returns +false+.
1402
 */
1403
static VALUE
1404
rb_complex_exact_p(VALUE self)
1405
{
1406
    get_dat1(self);
1407

  
1408
    if (RTEST(rb_funcall(dat->real, id_exact_p, 0)) &&
1409
        RTEST(rb_funcall(dat->imag, id_exact_p, 0))) {
1410
	return Qtrue;
1411
    }
1412
    return Qfalse;
1413
}
1414

  
1396 1415
/*
1397 1416
 * call-seq:
1398 1417
 *    cmp.finite?  ->  true or false
......
2284 2303
    id_real_p = rb_intern("real?");
2285 2304
    id_i_real = rb_intern("@real");
2286 2305
    id_i_imag = rb_intern("@image"); /* @image, not @imag */
2306
    id_exact_p = rb_intern("exact?");
2287 2307
    id_finite_p = rb_intern("finite?");
2288 2308
    id_infinite_p = rb_intern("infinite?");
2289 2309
    id_rationalize = rb_intern("rationalize");
......
2358 2378
    rb_undef_method(rb_cComplex, "positive?");
2359 2379
    rb_undef_method(rb_cComplex, "negative?");
2360 2380

  
2381
    rb_define_method(rb_cComplex, "exact?", rb_complex_exact_p, 0);
2361 2382
    rb_define_method(rb_cComplex, "finite?", rb_complex_finite_p, 0);
2362 2383
    rb_define_method(rb_cComplex, "infinite?", rb_complex_infinite_p, 0);
2363 2384

  
ext/bigdecimal/bigdecimal.c
687 687
    return Qfalse;
688 688
}
689 689

  
690
/* Returns false as BigDecimal is not exact.  */
691
static VALUE
692
BigDecimal_IsExact(VALUE self)
693
{
694
    return Qfalse;
695
}
696

  
690 697
/* Returns nil, -1, or +1 depending on whether the value is finite,
691 698
 * -Infinity, or +Infinity.
692 699
 */
......
3493 3500
    rb_define_method(rb_cBigDecimal, "exponent", BigDecimal_exponent, 0);
3494 3501
    rb_define_method(rb_cBigDecimal, "sign", BigDecimal_sign, 0);
3495 3502
    rb_define_method(rb_cBigDecimal, "nan?",      BigDecimal_IsNaN, 0);
3503
    rb_define_method(rb_cBigDecimal, "exact?", BigDecimal_IsExact, 0);
3496 3504
    rb_define_method(rb_cBigDecimal, "infinite?", BigDecimal_IsInfinite, 0);
3497 3505
    rb_define_method(rb_cBigDecimal, "finite?",   BigDecimal_IsFinite, 0);
3498 3506
    rb_define_method(rb_cBigDecimal, "truncate",  BigDecimal_truncate, -1);
numeric.c
795 795
    return num;
796 796
}
797 797

  
798
/*
799
 *  call-seq:
800
 *     num.exact?  ->  true or false
801
 *
802
 *  Returns +true+ if +num+ is an exact number, otherwise returns +false+.
803
 */
804
static VALUE
805
num_exact_p(VALUE num)
806
{
807
    return Qtrue;
808
}
809

  
798 810
/*
799 811
 *  call-seq:
800 812
 *     num.finite?  ->  true or false
......
1731 1743
    return isnan(value) ? Qtrue : Qfalse;
1732 1744
}
1733 1745

  
1746
/*
1747
 *  call-seq:
1748
 *     float.exact?  ->  false
1749
 *
1750
 *  Returns +false+, as floating point numbers are not exact.
1751
 */
1752

  
1753
static VALUE
1754
flo_is_exact_p(VALUE num)
1755
{
1756
    return Qfalse;
1757
}
1758

  
1734 1759
/*
1735 1760
 *  call-seq:
1736 1761
 *     float.infinite?  ->  -1, 1, or nil
......
5586 5611
    rb_define_method(rb_cNumeric, "integer?", num_int_p, 0);
5587 5612
    rb_define_method(rb_cNumeric, "zero?", num_zero_p, 0);
5588 5613
    rb_define_method(rb_cNumeric, "nonzero?", num_nonzero_p, 0);
5614
    rb_define_method(rb_cNumeric, "exact?", num_exact_p, 0);
5589 5615
    rb_define_method(rb_cNumeric, "finite?", num_finite_p, 0);
5590 5616
    rb_define_method(rb_cNumeric, "infinite?", num_infinite_p, 0);
5591 5617

  
......
5808 5834
    rb_define_method(rb_cFloat, "truncate", flo_truncate, -1);
5809 5835

  
5810 5836
    rb_define_method(rb_cFloat, "nan?",      flo_is_nan_p, 0);
5837
    rb_define_method(rb_cFloat, "exact?",    flo_is_exact_p, 0);
5811 5838
    rb_define_method(rb_cFloat, "infinite?", rb_flo_is_infinite_p, 0);
5812 5839
    rb_define_method(rb_cFloat, "finite?",   rb_flo_is_finite_p, 0);
5813 5840
    rb_define_method(rb_cFloat, "next_float", flo_next_float, 0);
test/bigdecimal/test_bigdecimal.rb
477 477
    assert_nan(BigDecimal("NaN").nonzero?)
478 478
  end
479 479

  
480
  def test_exact_p
481
    assert_not_predicate(BigDecimal('0.0'), :exact?)
482
  end
483

  
480 484
  def test_double_fig
481 485
    assert_kind_of(Integer, BigDecimal.double_fig)
482 486
  end
test/ruby/test_complex.rb
36 36
    assert_equal([true, true], [c.eql?(c1), c1.eql?(c)])
37 37
  end
38 38

  
39
  def test_exact_p
40
    assert_predicate(Complex(1), :exact?)
41
    assert_not_predicate(Complex(1, 1.0), :exact?)
42
    assert_not_predicate(Complex(1.0, 1), :exact?)
43
    assert_not_predicate(Complex(1.0, 1.0), :exact?)
44
  end
45

  
39 46
  def test_eql_p
40 47
    c = Complex(0)
41 48
    c2 = Complex(0)
test/ruby/test_float.rb
59 59
    assert_equal(a == b, b == a)
60 60
  end
61 61

  
62
  def test_exact_p
63
    assert_not_predicate(1.0, :exact?)
64
  end
65

  
62 66
  def test_cmp_int
63 67
    100.times {|i|
64 68
      int0 = 1 << i
test/ruby/test_integer.rb
247 247
    end;
248 248
  end
249 249

  
250
  def test_exact_p
251
    assert_predicate(1, :exact?)
252
  end
253

  
250 254
  def test_int_p
251 255
    assert_not_predicate(1.0, :integer?)
252 256
    assert_predicate(1, :integer?)
test/ruby/test_rational.rb
30 30
    assert_equal([true, true], [c.eql?(c1), c1.eql?(c)])
31 31
  end
32 32

  
33
  def test_exact_p
34
    assert_predicate(Rational(1), :exact?)
35
  end
36

  
33 37
  def test_eql_p
34 38
    c = Rational(0)
35 39
    c2 = Rational(0)
36
-