(linenum→info "unix/slp.c:2238")

ruby/1.9.0/numeric.c

    1: /**********************************************************************
    2: 
    3:   numeric.c -
    4: 
    5:   $Author: usa $
    6:   $Date: 2007-12-25 03:12:24 +0900 (Tue, 25 Dec 2007) $
    7:   created at: Fri Aug 13 18:33:09 JST 1993
    8: 
    9:   Copyright (C) 1993-2007 Yukihiro Matsumoto
   10: 
   11: **********************************************************************/
   12: 
   13: #include "ruby/ruby.h"
   14: #include "ruby/encoding.h"
   15: #include <ctype.h>
   16: #include <math.h>
   17: #include <stdio.h>
   18: 
   19: #if defined(__FreeBSD__) && __FreeBSD__ < 4
   20: #include <floatingpoint.h>
   21: #endif
   22: 
   23: #ifdef HAVE_FLOAT_H
   24: #include <float.h>
   25: #endif
   26: 
   27: #ifdef HAVE_IEEEFP_H
   28: #include <ieeefp.h>
   29: #endif
   30: 
   31: /* use IEEE 64bit values if not defined */
   32: #ifndef FLT_RADIX
   33: #define FLT_RADIX 2
   34: #endif
   35: #ifndef FLT_ROUNDS
   36: #define FLT_ROUNDS 1
   37: #endif
   38: #ifndef DBL_MIN
   39: #define DBL_MIN 2.2250738585072014e-308
   40: #endif
   41: #ifndef DBL_MAX
   42: #define DBL_MAX 1.7976931348623157e+308
   43: #endif
   44: #ifndef DBL_MIN_EXP
   45: #define DBL_MIN_EXP (-1021)
   46: #endif
   47: #ifndef DBL_MAX_EXP
   48: #define DBL_MAX_EXP 1024
   49: #endif
   50: #ifndef DBL_MIN_10_EXP
   51: #define DBL_MIN_10_EXP (-307)
   52: #endif
   53: #ifndef DBL_MAX_10_EXP
   54: #define DBL_MAX_10_EXP 308
   55: #endif
   56: #ifndef DBL_DIG
   57: #define DBL_DIG 15
   58: #endif
   59: #ifndef DBL_MANT_DIG
   60: #define DBL_MANT_DIG 53
   61: #endif
   62: #ifndef DBL_EPSILON
   63: #define DBL_EPSILON 2.2204460492503131e-16
   64: #endif
   65: 
   66: #ifndef HAVE_ROUND
   67: double
   68: round(double x)
   69: {
   70:     double f;
   71: 
   72:     if (x > 0.0) {
   73:         f = floor(x);
   74:         x = f + (x - f >= 0.5);
   75:     }
   76:     else if (x < 0.0) {
   77:         f = ceil(x);
   78:         x = f - (f - x >= 0.5);
   79:     }
   80:     return x;
   81: }
   82: #endif
   83: 
   84: static ID id_coerce, id_to_i, id_eq;
   85: 
   86: VALUE rb_cNumeric;
   87: VALUE rb_cFloat;
   88: VALUE rb_cInteger;
   89: VALUE rb_cFixnum;
   90: 
   91: VALUE rb_eZeroDivError;
   92: VALUE rb_eFloatDomainError;
   93: 
   94: void
   95: rb_num_zerodiv(void)
   96: {
   97:     rb_raise(rb_eZeroDivError, "divided by 0");
   98: }
   99: 
  100: 
  101: /*
  102:  *  call-seq:
  103:  *     num.coerce(numeric)   => array
  104:  *
  105:  *  If <i>aNumeric</i> is the same type as <i>num</i>, returns an array
  106:  *  containing <i>aNumeric</i> and <i>num</i>. Otherwise, returns an
  107:  *  array with both <i>aNumeric</i> and <i>num</i> represented as
  108:  *  <code>Float</code> objects. This coercion mechanism is used by
  109:  *  Ruby to handle mixed-type numeric operations: it is intended to
  110:  *  find a compatible common type between the two operands of the operator.
  111:  *
  112:  *     1.coerce(2.5)   #=> [2.5, 1.0]
  113:  *     1.2.coerce(3)   #=> [3.0, 1.2]
  114:  *     1.coerce(2)     #=> [2, 1]
  115:  */
  116: 
  117: static VALUE
  118: num_coerce(VALUE x, VALUE y)
  119: {
  120:     if (CLASS_OF(x) == CLASS_OF(y))
  121:         return rb_assoc_new(y, x);
  122:     return rb_assoc_new(rb_Float(y), rb_Float(x));
  123: }
  124: 
  125: static VALUE
  126: coerce_body(VALUE *x)
  127: {
  128:     return rb_funcall(x[1], id_coerce, 1, x[0]);
  129: }
  130: 
  131: static VALUE
  132: coerce_rescue(VALUE *x)
  133: {
  134:     volatile VALUE v = rb_inspect(x[1]);
  135: 
  136:     rb_raise(rb_eTypeError, "%s can't be coerced into %s",
  137:              rb_special_const_p(x[1])?
  138:              RSTRING_PTR(v):
  139:              rb_obj_classname(x[1]),
  140:              rb_obj_classname(x[0]));
  141:     return Qnil;                /* dummy */
  142: }
  143: 
  144: static int
  145: do_coerce(VALUE *x, VALUE *y, int err)
  146: {
  147:     VALUE ary;
  148:     VALUE a[2];
  149: 
  150:     a[0] = *x; a[1] = *y;
  151: 
  152:     ary = rb_rescue(coerce_body, (VALUE)a, err?coerce_rescue:0, (VALUE)a);
  153:     if (TYPE(ary) != T_ARRAY || RARRAY_LEN(ary) != 2) {
  154:         if (err) {
  155:             rb_raise(rb_eTypeError, "coerce must return [x, y]");
  156:         }
  157:         return Qfalse;
  158:     }
  159: 
  160:     *x = RARRAY_PTR(ary)[0];
  161:     *y = RARRAY_PTR(ary)[1];
  162:     return Qtrue;
  163: }
  164: 
  165: VALUE
  166: rb_num_coerce_bin(VALUE x, VALUE y)
  167: {
  168:     do_coerce(&x, &y, Qtrue);
  169:     return rb_funcall(x, rb_frame_this_func(), 1, y);
  170: }
  171: 
  172: VALUE
  173: rb_num_coerce_cmp(VALUE x, VALUE y)
  174: {
  175:     if (do_coerce(&x, &y, Qfalse))
  176:         return rb_funcall(x, rb_frame_this_func(), 1, y);
  177:     return Qnil;
  178: }
  179: 
  180: VALUE
  181: rb_num_coerce_relop(VALUE x, VALUE y)
  182: {
  183:     VALUE c, x0 = x, y0 = y;
  184: 
  185:     if (!do_coerce(&x, &y, Qfalse) ||
  186:         NIL_P(c = rb_funcall(x, rb_frame_this_func(), 1, y))) {
  187:         rb_cmperr(x0, y0);
  188:         return Qnil;           /* not reached */
  189:     }
  190:     return c;
  191: }
  192: 
  193: /*
  194:  * Trap attempts to add methods to <code>Numeric</code> objects. Always
  195:  * raises a <code>TypeError</code>
  196:  */
  197: 
  198: static VALUE
  199: num_sadded(VALUE x, VALUE name)
  200: {
  201:     /* ruby_frame = ruby_frame->prev; */ /* pop frame for "singleton_method_added" */
  202:     /* Numerics should be values; singleton_methods should not be added to them */
  203:     rb_raise(rb_eTypeError,
  204:              "can't define singleton method \"%s\" for %s",
  205:              rb_id2name(rb_to_id(name)),
  206:              rb_obj_classname(x));
  207:     return Qnil;                /* not reached */
  208: }
  209: 
  210: /* :nodoc: */
  211: static VALUE
  212: num_init_copy(VALUE x, VALUE y)
  213: {
  214:     /* Numerics are immutable values, which should not be copied */
  215:     rb_raise(rb_eTypeError, "can't copy %s", rb_obj_classname(x));
  216:     return Qnil;                /* not reached */
  217: }
  218: 
  219: /*
  220:  *  call-seq:
  221:  *     +num    => num
  222:  *
  223:  *  Unary Plus---Returns the receiver's value.
  224:  */
  225: 
  226: static VALUE
  227: num_uplus(VALUE num)
  228: {
  229:     return num;
  230: }
  231: 
  232: /*
  233:  *  call-seq:
  234:  *     -num    => numeric
  235:  *
  236:  *  Unary Minus---Returns the receiver's value, negated.
  237:  */
  238: 
  239: static VALUE
  240: num_uminus(VALUE num)
  241: {
  242:     VALUE zero;
  243: 
  244:     zero = INT2FIX(0);
  245:     do_coerce(&zero, &num, Qtrue);
  246: 
  247:     return rb_funcall(zero, '-', 1, num);
  248: }
  249: 
  250: /*
  251:  *  call-seq:
  252:  *     num.quo(numeric)    =>   result
  253:  *     num.fdiv(numeric)   =>   result
  254:  *
  255:  *  Equivalent to <code>Numeric#/</code>, but overridden in subclasses.
  256:  */
  257: 
  258: static VALUE
  259: num_quo(VALUE x, VALUE y)
  260: {
  261:     return rb_funcall(x, '/', 1, y);
  262: }
  263: 
  264: 
  265: static VALUE num_floor(VALUE num);
  266: 
  267: /*
  268:  *  call-seq:
  269:  *     num.div(numeric)    => integer
  270:  *
  271:  *  Uses <code>/</code> to perform division, then converts the result to
  272:  *  an integer. <code>Numeric</code> does not define the <code>/</code>
  273:  *  operator; this is left to subclasses.
  274:  */
  275: 
  276: static VALUE
  277: num_div(VALUE x, VALUE y)
  278: {
  279:     return num_floor(rb_funcall(x, '/', 1, y));
  280: }
  281: 
  282: 
  283: /*
  284:  *  call-seq:
  285:  *     num.divmod( aNumeric ) -> anArray
  286:  *
  287:  *  Returns an array containing the quotient and modulus obtained by
  288:  *  dividing <i>num</i> by <i>aNumeric</i>. If <code>q, r =
  289:  *  x.divmod(y)</code>, then
  290:  *
  291:  *      q = floor(float(x)/float(y))
  292:  *      x = q*y + r
  293:  *
  294:  *  The quotient is rounded toward -infinity, as shown in the following table:
  295:  *
  296:  *     a    |  b  |  a.divmod(b)  |   a/b   | a.modulo(b) | a.remainder(b)
  297:  *    ------+-----+---------------+---------+-------------+---------------
  298:  *     13   |  4  |   3,    1     |   3     |    1        |     1
  299:  *    ------+-----+---------------+---------+-------------+---------------
  300:  *     13   | -4  |  -4,   -3     |  -3     |   -3        |     1
  301:  *    ------+-----+---------------+---------+-------------+---------------
  302:  *    -13   |  4  |  -4,    3     |  -4     |    3        |    -1
  303:  *    ------+-----+---------------+---------+-------------+---------------
  304:  *    -13   | -4  |   3,   -1     |   3     |   -1        |    -1
  305:  *    ------+-----+---------------+---------+-------------+---------------
  306:  *     11.5 |  4  |   2,    3.5   |   2.875 |    3.5      |     3.5
  307:  *    ------+-----+---------------+---------+-------------+---------------
  308:  *     11.5 | -4  |  -3,   -0.5   |  -2.875 |   -0.5      |     3.5
  309:  *    ------+-----+---------------+---------+-------------+---------------
  310:  *    -11.5 |  4  |  -3,    0.5   |  -2.875 |    0.5      |    -3.5
  311:  *    ------+-----+---------------+---------+-------------+---------------
  312:  *    -11.5 | -4  |   2,   -3.5   |   2.875 |   -3.5      |    -3.5
  313:  *
  314:  *
  315:  *  Examples
  316:  *     11.divmod(3)         #=> [3, 2]
  317:  *     11.divmod(-3)        #=> [-4, -1]
  318:  *     11.divmod(3.5)       #=> [3, 0.5]
  319:  *     (-11).divmod(3.5)    #=> [-4, 3.0]
  320:  *     (11.5).divmod(3.5)   #=> [3, 1.0]
  321:  */
  322: 
  323: static VALUE
  324: num_divmod(VALUE x, VALUE y)
  325: {
  326:     return rb_assoc_new(num_div(x, y), rb_funcall(x, '%', 1, y));
  327: }
  328: 
  329: /*
  330:  *  call-seq:
  331:  *     num.modulo(numeric)    => result
  332:  *
  333:  *  Equivalent to
  334:  *  <i>num</i>.<code>divmod(</code><i>aNumeric</i><code>)[1]</code>.
  335:  */
  336: 
  337: static VALUE
  338: num_modulo(VALUE x, VALUE y)
  339: {
  340:     return rb_funcall(x, '%', 1, y);
  341: }
  342: 
  343: /*
  344:  *  call-seq:
  345:  *     num.remainder(numeric)    => result
  346:  *
  347:  *  If <i>num</i> and <i>numeric</i> have different signs, returns
  348:  *  <em>mod</em>-<i>numeric</i>; otherwise, returns <em>mod</em>. In
  349:  *  both cases <em>mod</em> is the value
  350:  *  <i>num</i>.<code>modulo(</code><i>numeric</i><code>)</code>. The
  351:  *  differences between <code>remainder</code> and modulo
  352:  *  (<code>%</code>) are shown in the table under <code>Numeric#divmod</code>.
  353:  */
  354: 
  355: static VALUE
  356: num_remainder(VALUE x, VALUE y)
  357: {
  358:     VALUE z = rb_funcall(x, '%', 1, y);
  359: 
  360:     if ((!rb_equal(z, INT2FIX(0))) &&
  361:         ((RTEST(rb_funcall(x, '<', 1, INT2FIX(0))) &&
  362:           RTEST(rb_funcall(y, '>', 1, INT2FIX(0)))) ||
  363:          (RTEST(rb_funcall(x, '>', 1, INT2FIX(0))) &&
  364:           RTEST(rb_funcall(y, '<', 1, INT2FIX(0)))))) {
  365:         return rb_funcall(z, '-', 1, y);
  366:     }
  367:     return z;
  368: }
  369: 
  370: /*
  371:  *  call-seq:
  372:  *     num.scalar? -> true or false
  373:  *
  374:  *  Returns <code>true</code> if <i>num</i> is an <code>Scalar</code>
  375:  *  (i.e. non <code>Complex</code>).
  376:  */
  377: 
  378: static VALUE
  379: num_scalar_p(VALUE num)
  380: {
  381:     return Qtrue;
  382: }
  383: 
  384: /*
  385:  *  call-seq:
  386:  *     num.integer? -> true or false
  387:  *
  388:  *  Returns <code>true</code> if <i>num</i> is an <code>Integer</code>
  389:  *  (including <code>Fixnum</code> and <code>Bignum</code>).
  390:  */
  391: 
  392: static VALUE
  393: num_int_p(VALUE num)
  394: {
  395:     return Qfalse;
  396: }
  397: 
  398: /*
  399:  *  call-seq:
  400:  *     num.abs   => num or numeric
  401:  *
  402:  *  Returns the absolute value of <i>num</i>.
  403:  *
  404:  *     12.abs         #=> 12
  405:  *     (-34.56).abs   #=> 34.56
  406:  *     -34.56.abs     #=> 34.56
  407:  */
  408: 
  409: static VALUE
  410: num_abs(VALUE num)
  411: {
  412:     if (RTEST(rb_funcall(num, '<', 1, INT2FIX(0)))) {
  413:         return rb_funcall(num, rb_intern("-@"), 0);
  414:     }
  415:     return num;
  416: }
  417: 
  418: 
  419: /*
  420:  *  call-seq:
  421:  *     num.zero?    => true or false
  422:  *
  423:  *  Returns <code>true</code> if <i>num</i> has a zero value.
  424:  */
  425: 
  426: static VALUE
  427: num_zero_p(VALUE num)
  428: {
  429:     if (rb_equal(num, INT2FIX(0))) {
  430:         return Qtrue;
  431:     }
  432:     return Qfalse;
  433: }
  434: 
  435: 
  436: /*
  437:  *  call-seq:
  438:  *     num.nonzero?    => num or nil
  439:  *
  440:  *  Returns <i>num</i> if <i>num</i> is not zero, <code>nil</code>
  441:  *  otherwise. This behavior is useful when chaining comparisons:
  442:  *
  443:  *     a = %w( z Bb bB bb BB a aA Aa AA A )
  444:  *     b = a.sort {|a,b| (a.downcase <=> b.downcase).nonzero? || a <=> b }
  445:  *     b   #=> ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"]
  446:  */
  447: 
  448: static VALUE
  449: num_nonzero_p(VALUE num)
  450: {
  451:     if (RTEST(rb_funcall(num, rb_intern("zero?"), 0, 0))) {
  452:         return Qnil;
  453:     }
  454:     return num;
  455: }
  456: 
  457: /*
  458:  *  call-seq:
  459:  *     num.to_int    => integer
  460:  *
  461:  *  Invokes the child class's <code>to_i</code> method to convert
  462:  *  <i>num</i> to an integer.
  463:  */
  464: 
  465: static VALUE
  466: num_to_int(VALUE num)
  467: {
  468:     return rb_funcall(num, id_to_i, 0, 0);
  469: }
  470: 
  471: 
  472: /********************************************************************
  473:  *
  474:  * Document-class: Float
  475:  *
  476:  *  <code>Float</code> objects represent real numbers using the native
  477:  *  architecture's double-precision floating point representation.
  478:  */
  479: 
  480: VALUE
  481: rb_float_new(double d)
  482: {
  483:     NEWOBJ(flt, struct RFloat);
  484:     OBJSETUP(flt, rb_cFloat, T_FLOAT);
  485: 
  486:     flt->float_value = d;
  487:     return (VALUE)flt;
  488: }
  489: 
  490: /*
  491:  *  call-seq:
  492:  *     flt.to_s    => string
  493:  *
  494:  *  Returns a string containing a representation of self. As well as a
  495:  *  fixed or exponential form of the number, the call may return
  496:  *  ``<code>NaN</code>'', ``<code>Infinity</code>'', and
  497:  *  ``<code>-Infinity</code>''.
  498:  */
  499: 
  500: static VALUE
  501: flo_to_s(VALUE flt)
  502: {
  503:     char buf[32];
  504:     double value = RFLOAT_VALUE(flt);
  505:     char *p, *e;
  506: 
  507:     if (isinf(value))
  508:         return rb_str_new2(value < 0 ? "-Infinity" : "Infinity");
  509:     else if(isnan(value))
  510:         return rb_str_new2("NaN");
  511: 
  512:     sprintf(buf, "%#.15g", value); /* ensure to print decimal point */
  513:     if (!(e = strchr(buf, 'e'))) {
  514:         e = buf + strlen(buf);
  515:     }
  516:     if (!ISDIGIT(e[-1])) { /* reformat if ended with decimal point (ex 111111111111111.) */
  517:         sprintf(buf, "%#.14e", value);
  518:         if (!(e = strchr(buf, 'e'))) {
  519:             e = buf + strlen(buf);
  520:         }
  521:     }
  522:     p = e;
  523:     while (p[-1]=='0' && ISDIGIT(p[-2]))
  524:         p--;
  525:     memmove(p, e, strlen(e)+1);
  526:     return rb_str_new2(buf);
  527: }
  528: 
  529: /*
  530:  * MISSING: documentation
  531:  */
  532: 
  533: static VALUE
  534: flo_coerce(VALUE x, VALUE y)
  535: {
  536:     return rb_assoc_new(rb_Float(y), x);
  537: }
  538: 
  539: /*
  540:  * call-seq:
  541:  *    -float   => float
  542:  *
  543:  * Returns float, negated.
  544:  */
  545: 
  546: static VALUE
  547: flo_uminus(VALUE flt)
  548: {
  549:     return DOUBLE2NUM(-RFLOAT_VALUE(flt));
  550: }
  551: 
  552: /*
  553:  * call-seq:
  554:  *   float + other   => float
  555:  *
  556:  * Returns a new float which is the sum of <code>float</code>
  557:  * and <code>other</code>.
  558:  */
  559: 
  560: static VALUE
  561: flo_plus(VALUE x, VALUE y)
  562: {
  563:     switch (TYPE(y)) {
  564:       case T_FIXNUM:
  565:         return DOUBLE2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
  566:       case T_BIGNUM:
  567:         return DOUBLE2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y));
  568:       case T_FLOAT:
  569:         return DOUBLE2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
  570:       default:
  571:         return rb_num_coerce_bin(x, y);
  572:     }
  573: }
  574: 
  575: /*
  576:  * call-seq:
  577:  *   float + other   => float
  578:  *
  579:  * Returns a new float which is the difference of <code>float</code>
  580:  * and <code>other</code>.
  581:  */
  582: 
  583: static VALUE
  584: flo_minus(VALUE x, VALUE y)
  585: {
  586:     switch (TYPE(y)) {
  587:       case T_FIXNUM:
  588:         return DOUBLE2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
  589:       case T_BIGNUM:
  590:         return DOUBLE2NUM(RFLOAT_VALUE(x) - rb_big2dbl(y));
  591:       case T_FLOAT:
  592:         return DOUBLE2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y));
  593:       default:
  594:         return rb_num_coerce_bin(x, y);
  595:     }
  596: }
  597: 
  598: /*
  599:  * call-seq:
  600:  *   float * other   => float
  601:  *
  602:  * Returns a new float which is the product of <code>float</code>
  603:  * and <code>other</code>.
  604:  */
  605: 
  606: static VALUE
  607: flo_mul(VALUE x, VALUE y)
  608: {
  609:     switch (TYPE(y)) {
  610:       case T_FIXNUM:
  611:         return DOUBLE2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y));
  612:       case T_BIGNUM:
  613:         return DOUBLE2NUM(RFLOAT_VALUE(x) * rb_big2dbl(y));
  614:       case T_FLOAT:
  615:         return DOUBLE2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y));
  616:       default:
  617:         return rb_num_coerce_bin(x, y);
  618:     }
  619: }
  620: 
  621: /*
  622:  * call-seq:
  623:  *   float / other   => float
  624:  *
  625:  * Returns a new float which is the result of dividing
  626:  * <code>float</code> by <code>other</code>.
  627:  */
  628: 
  629: static VALUE
  630: flo_div(VALUE x, VALUE y)
  631: {
  632:     long f_y;
  633:     double d;
  634: 
  635:     switch (TYPE(y)) {
  636:       case T_FIXNUM:
  637:         f_y = FIX2LONG(y);
  638:         return DOUBLE2NUM(RFLOAT_VALUE(x) / (double)f_y);
  639:       case T_BIGNUM:
  640:         d = rb_big2dbl(y);
  641:         return DOUBLE2NUM(RFLOAT_VALUE(x) / d);
  642:       case T_FL