~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to complex.c

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
  complex.c: Coded by Tadayoshi Funaba 2008,2009
 
2
  complex.c: Coded by Tadayoshi Funaba 2008-2011
3
3
 
4
4
  This implementation is based on Keiju Ishitsuka's Complex library
5
5
  which is written in ruby.
6
6
*/
7
7
 
8
8
#include "ruby.h"
 
9
#include "internal.h"
9
10
#include <math.h>
10
11
 
11
12
#define NDEBUG
28
29
inline static VALUE \
29
30
f_##n(VALUE x, VALUE y)\
30
31
{\
31
 
    return rb_funcall(x, op, 1, y);\
 
32
    return rb_funcall(x, (op), 1, y);\
32
33
}
33
34
 
34
35
#define fun1(n) \
162
163
fun1(real)
163
164
fun1(real_p)
164
165
 
165
 
fun1(to_f)
166
 
fun1(to_i)
 
166
inline static VALUE
 
167
f_to_i(VALUE x)
 
168
{
 
169
    if (TYPE(x) == T_STRING)
 
170
        return rb_str_to_inum(x, 10, 0);
 
171
    return rb_funcall(x, id_to_i, 0);
 
172
}
 
173
inline static VALUE
 
174
f_to_f(VALUE x)
 
175
{
 
176
    if (TYPE(x) == T_STRING)
 
177
        return DBL2NUM(rb_str_to_dbl(x, 0));
 
178
    return rb_funcall(x, id_to_f, 0);
 
179
}
 
180
 
167
181
fun1(to_r)
168
182
fun1(to_s)
169
183
 
359
373
#ifdef CANON
360
374
static int canonicalization = 0;
361
375
 
362
 
void
 
376
RUBY_FUNC_EXPORTED void
363
377
nucomp_canonicalization(int f)
364
378
{
365
379
    canonicalization = f;
472
486
}
473
487
 
474
488
#define imp1(n) \
475
 
extern VALUE rb_math_##n(VALUE x);\
476
489
inline static VALUE \
477
490
m_##n##_bang(VALUE x)\
478
491
{\
480
493
}
481
494
 
482
495
#define imp2(n) \
483
 
extern VALUE rb_math_##n(VALUE x, VALUE y);\
484
496
inline static VALUE \
485
497
m_##n##_bang(VALUE x, VALUE y)\
486
498
{\
493
505
imp1(exp)
494
506
imp2(hypot)
495
507
 
496
 
#define m_hypot(x,y) m_hypot_bang(x,y)
497
 
 
498
 
extern VALUE rb_math_log(int argc, VALUE *argv);
 
508
#define m_hypot(x,y) m_hypot_bang((x),(y))
499
509
 
500
510
static VALUE
501
511
m_log_bang(VALUE x)
576
586
 *    Complex.polar(abs[, arg])  ->  complex
577
587
 *
578
588
 * Returns a complex object which denotes the given polar form.
 
589
 *
 
590
 *   Complex.polar(3, 0)           #=> (3.0+0.0i)
 
591
 *   Complex.polar(3, Math::PI/2)  #=> (1.836909530733566e-16+3.0i)
 
592
 *   Complex.polar(3, Math::PI)    #=> (-3.0+3.673819061467132e-16i)
 
593
 *   Complex.polar(3, -Math::PI/2) #=> (1.836909530733566e-16-3.0i)
579
594
 */
580
595
static VALUE
581
596
nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
824
839
static VALUE
825
840
nucomp_expt(VALUE self, VALUE other)
826
841
{
827
 
    if (k_exact_zero_p(other))
 
842
    if (k_numeric_p(other) && k_exact_zero_p(other))
828
843
        return f_complex_new_bang1(CLASS_OF(self), ONE);
829
844
 
830
845
    if (k_rational_p(other) && f_one_p(f_denominator(other)))
985
1000
 *    cmp.phase  ->  float
986
1001
 *
987
1002
 * Returns the angle part of its polar form.
 
1003
 *
 
1004
 *   Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966
 
1005
 *
988
1006
 */
989
1007
static VALUE
990
1008
nucomp_arg(VALUE self)
1071
1089
}
1072
1090
#endif
1073
1091
 
1074
 
extern VALUE rb_lcm(VALUE x, VALUE y);
1075
 
 
1076
1092
/*
1077
1093
 * call-seq:
1078
1094
 *    cmp.denominator  ->  integer
1079
1095
 *
1080
 
 * Returns the denominator (lcm of both denominator, real and imag).
 
1096
 * Returns the denominator (lcm of both denominator - real and imag).
1081
1097
 *
1082
1098
 * See numerator.
1083
1099
 */
1157
1173
inline static VALUE
1158
1174
f_signbit(VALUE x)
1159
1175
{
 
1176
#if defined(HAVE_SIGNBIT) && defined(__GNUC__) && defined(__sun__) && \
 
1177
    !defined(signbit)
 
1178
    extern int signbit(double);
 
1179
#endif
1160
1180
    switch (TYPE(x)) {
1161
1181
      case T_FLOAT: {
1162
1182
        double f = RFLOAT_VALUE(x);
1319
1339
 * call-seq:
1320
1340
 *    cmp.to_r  ->  rational
1321
1341
 *
1322
 
 * Returns the value as a rational if possible.
 
1342
 * If the imaginary part is exactly 0, returns the real part as a Rational,
 
1343
 * otherwise a RangeError is raised.
1323
1344
 */
1324
1345
static VALUE
1325
1346
nucomp_to_r(VALUE self)
1338
1359
 * call-seq:
1339
1360
 *    cmp.rationalize([eps])  ->  rational
1340
1361
 *
1341
 
 * Returns the value as a rational if possible.  An optional argument
1342
 
 * eps is always ignored.
 
1362
 * If the imaginary part is exactly 0, returns the real part as a Rational,
 
1363
 * otherwise a RangeError is raised.
1343
1364
 */
1344
1365
static VALUE
1345
1366
nucomp_rationalize(int argc, VALUE *argv, VALUE self)
1346
1367
{
 
1368
    get_dat1(self);
 
1369
 
1347
1370
    rb_scan_args(argc, argv, "01", NULL);
1348
 
    return nucomp_to_r(self);
 
1371
 
 
1372
    if (k_inexact_p(dat->imag) || f_nonzero_p(dat->imag)) {
 
1373
       VALUE s = f_to_s(self);
 
1374
       rb_raise(rb_eRangeError, "can't convert %s into Rational",
 
1375
                StringValuePtr(s));
 
1376
    }
 
1377
    return rb_funcall(dat->real, rb_intern("rationalize"), argc, argv);
1349
1378
}
1350
1379
 
1351
1380
/*
1422
1451
}
1423
1452
 
1424
1453
#define id_match rb_intern("match")
1425
 
#define f_match(x,y) rb_funcall(x, id_match, 1, y)
1426
 
 
1427
 
#define id_aref rb_intern("[]")
1428
 
#define f_aref(x,y) rb_funcall(x, id_aref, 1, y)
1429
 
 
1430
 
#define id_post_match rb_intern("post_match")
1431
 
#define f_post_match(x) rb_funcall(x, id_post_match, 0)
1432
 
 
1433
 
#define id_split rb_intern("split")
1434
 
#define f_split(x,y) rb_funcall(x, id_split, 1, y)
1435
 
 
1436
 
#define id_include_p rb_intern("include?")
1437
 
#define f_include_p(x,y) rb_funcall(x, id_include_p, 1, y)
1438
 
 
1439
 
#define id_count rb_intern("count")
1440
 
#define f_count(x,y) rb_funcall(x, id_count, 1, y)
 
1454
#define f_match(x,y) rb_funcall((x), id_match, 1, (y))
1441
1455
 
1442
1456
#define id_gsub_bang rb_intern("gsub!")
1443
 
#define f_gsub_bang(x,y,z) rb_funcall(x, id_gsub_bang, 2, y, z)
 
1457
#define f_gsub_bang(x,y,z) rb_funcall((x), id_gsub_bang, 2, (y), (z))
1444
1458
 
1445
1459
static VALUE
1446
1460
string_to_c_internal(VALUE self)
1458
1472
 
1459
1473
        m = f_match(comp_pat0, s);
1460
1474
        if (!NIL_P(m)) {
1461
 
          sr = f_aref(m, INT2FIX(1));
1462
 
          si = f_aref(m, INT2FIX(2));
1463
 
          re = f_post_match(m);
1464
 
          po = 1;
 
1475
            sr = rb_reg_nth_match(1, m);
 
1476
            si = rb_reg_nth_match(2, m);
 
1477
            re = rb_reg_match_post(m);
 
1478
            po = 1;
1465
1479
        }
1466
1480
        if (NIL_P(m)) {
1467
1481
            m = f_match(comp_pat1, s);
1468
1482
            if (!NIL_P(m)) {
1469
1483
                sr = Qnil;
1470
 
                si = f_aref(m, INT2FIX(1));
 
1484
                si = rb_reg_nth_match(1, m);
1471
1485
                if (NIL_P(si))
1472
1486
                    si = rb_usascii_str_new2("");
1473
1487
                {
1474
1488
                    VALUE t;
1475
1489
 
1476
 
                    t = f_aref(m, INT2FIX(2));
 
1490
                    t = rb_reg_nth_match(2, m);
1477
1491
                    if (NIL_P(t))
1478
1492
                        t = rb_usascii_str_new2("1");
1479
1493
                    rb_str_concat(si, t);
1480
1494
                }
1481
 
                re = f_post_match(m);
 
1495
                re = rb_reg_match_post(m);
1482
1496
                po = 0;
1483
1497
            }
1484
1498
        }
1486
1500
            m = f_match(comp_pat2, s);
1487
1501
            if (NIL_P(m))
1488
1502
                return rb_assoc_new(Qnil, self);
1489
 
            sr = f_aref(m, INT2FIX(1));
1490
 
            if (NIL_P(f_aref(m, INT2FIX(2))))
 
1503
            sr = rb_reg_nth_match(1, m);
 
1504
            if (NIL_P(rb_reg_nth_match(2, m)))
1491
1505
                si = Qnil;
1492
1506
            else {
1493
1507
                VALUE t;
1494
1508
 
1495
 
                si = f_aref(m, INT2FIX(3));
1496
 
                t = f_aref(m, INT2FIX(4));
 
1509
                si = rb_reg_nth_match(3, m);
 
1510
                t = rb_reg_nth_match(4, m);
1497
1511
                if (NIL_P(t))
1498
1512
                    t = rb_usascii_str_new2("1");
1499
1513
                rb_str_concat(si, t);
1500
1514
            }
1501
 
            re = f_post_match(m);
 
1515
            re = rb_reg_match_post(m);
1502
1516
            po = 0;
1503
1517
        }
1504
1518
        r = INT2FIX(0);
1505
1519
        i = INT2FIX(0);
1506
1520
        if (!NIL_P(sr)) {
1507
 
            if (f_include_p(sr, a_slash))
 
1521
            if (strchr(RSTRING_PTR(sr), '/'))
1508
1522
                r = f_to_r(sr);
1509
 
            else if (f_gt_p(f_count(sr, a_dot_and_an_e), INT2FIX(0)))
 
1523
            else if (strpbrk(RSTRING_PTR(sr), ".eE"))
1510
1524
                r = f_to_f(sr);
1511
1525
            else
1512
1526
                r = f_to_i(sr);
1513
1527
        }
1514
1528
        if (!NIL_P(si)) {
1515
 
            if (f_include_p(si, a_slash))
 
1529
            if (strchr(RSTRING_PTR(si), '/'))
1516
1530
                i = f_to_r(si);
1517
 
            else if (f_gt_p(f_count(si, a_dot_and_an_e), INT2FIX(0)))
 
1531
            else if (strpbrk(RSTRING_PTR(si), ".eE"))
1518
1532
                i = f_to_f(si);
1519
1533
            else
1520
1534
                i = f_to_i(si);
1539
1553
}
1540
1554
 
1541
1555
#define id_gsub rb_intern("gsub")
1542
 
#define f_gsub(x,y,z) rb_funcall(x, id_gsub, 2, y, z)
 
1556
#define f_gsub(x,y,z) rb_funcall((x), id_gsub, 2, (y), (z))
1543
1557
 
1544
1558
/*
1545
1559
 * call-seq:
1646
1660
    if (argc == 1) {
1647
1661
        if (k_numeric_p(a1) && !f_real_p(a1))
1648
1662
            return a1;
1649
 
        /* expect raise exception for consistency */
 
1663
        /* should raise exception for consistency */
1650
1664
        if (!k_numeric_p(a1))
1651
1665
            return rb_convert_type(a1, T_COMPLEX, "Complex", "to_c");
1652
1666
    }