method
power
Ruby latest stable (v1_9_3_392)
-
0 notes -
Class: BigDecimal
- 1_8_6_287
- 1_8_7_72
- 1_8_7_330
- 1_9_1_378 (0)
- 1_9_2_180 (0)
- 1_9_3_125 (0)
- 1_9_3_392 (0)
- What's this?
Related methods
- Class methods (9)
-
double_fig
-
limit
-
_load
-
mode
-
new
-
save_exception_mode
-
save_limit
-
save_rounding_mode
-
ver
- Instance methods (53)
-
<
-
<=
-
<=>
-
==
-
===
-
>
-
>=
-
-
-
-@
-
/
-
*
-
**
-
%
-
+
-
+@
-
abs
-
add
-
ceil
-
coerce
-
div
-
divmod
-
_dump
-
eql?
-
exponent
-
finite?
-
fix
-
floor
-
frac
-
hash
-
infinite?
-
inspect
-
modulo
-
mult
-
nan?
-
nonzero?
-
power
-
precs
-
quo
-
remainder
-
round
-
sign
-
split
-
sqrt
-
sub
-
to_d
-
to_digits
-
to_f
-
to_i
-
to_int
-
to_r
-
to_s
-
truncate
-
zero?
= private
= protected
power(p1, p2 = v2)
public
Returns the value raised to the power of n. Note that n must be an Integer.
Also available as the operator **
Show source
static VALUE BigDecimal_power(int argc, VALUE*argv, VALUE self) { ENTER(5); VALUE vexp, prec; Real* exp = NULL; Real *x, *y; ssize_t mp, ma, n; SIGNED_VALUE int_exp; double d; rb_scan_args(argc, argv, "11", &vexp, &prec); GUARD_OBJ(x, GetVpValue(self, 1)); n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec); if (VpIsNaN(x)) { y = VpCreateRbObject(n, "0#"); RB_GC_GUARD(y->obj); VpSetNaN(y); return ToValue(y); } retry: switch (TYPE(vexp)) { case T_FIXNUM: break; case T_BIGNUM: break; case T_FLOAT: d = RFLOAT_VALUE(vexp); if (d == round(d)) { vexp = LL2NUM((LONG_LONG)round(d)); goto retry; } exp = GetVpValueWithPrec(vexp, DBL_DIG+1, 1); break; case T_RATIONAL: if (is_zero(RRATIONAL(vexp)->num)) { if (is_positive(vexp)) { vexp = INT2FIX(0); goto retry; } } else if (is_one(RRATIONAL(vexp)->den)) { vexp = RRATIONAL(vexp)->num; goto retry; } exp = GetVpValueWithPrec(vexp, n, 1); break; case T_DATA: if (is_kind_of_BigDecimal(vexp)) { VALUE zero = INT2FIX(0); VALUE rounded = BigDecimal_round(1, &zero, vexp); if (RTEST(BigDecimal_eq(vexp, rounded))) { vexp = BigDecimal_to_i(vexp); goto retry; } exp = DATA_PTR(vexp); break; } /* fall through */ default: rb_raise(rb_eTypeError, "wrong argument type %s (expected scalar Numeric)", rb_obj_classname(vexp)); } if (VpIsZero(x)) { if (is_negative(vexp)) { y = VpCreateRbObject(n, "#0"); RB_GC_GUARD(y->obj); if (VpGetSign(x) < 0) { if (is_integer(vexp)) { if (is_even(vexp)) { /* (-0) ** (-even_integer) -> Infinity */ VpSetPosInf(y); } else { /* (-0) ** (-odd_integer) -> -Infinity */ VpSetNegInf(y); } } else { /* (-0) ** (-non_integer) -> Infinity */ VpSetPosInf(y); } } else { /* (+0) ** (-num) -> Infinity */ VpSetPosInf(y); } return ToValue(y); } else if (is_zero(vexp)) { return ToValue(VpCreateRbObject(n, "1")); } else { return ToValue(VpCreateRbObject(n, "0")); } } if (is_zero(vexp)) { return ToValue(VpCreateRbObject(n, "1")); } else if (is_one(vexp)) { return self; } if (VpIsInf(x)) { if (is_negative(vexp)) { if (VpGetSign(x) < 0) { if (is_integer(vexp)) { if (is_even(vexp)) { /* (-Infinity) ** (-even_integer) -> +0 */ return ToValue(VpCreateRbObject(n, "0")); } else { /* (-Infinity) ** (-odd_integer) -> -0 */ return ToValue(VpCreateRbObject(n, "-0")); } } else { /* (-Infinity) ** (-non_integer) -> -0 */ return ToValue(VpCreateRbObject(n, "-0")); } } else { return ToValue(VpCreateRbObject(n, "0")); } } else { y = VpCreateRbObject(n, "0#"); if (VpGetSign(x) < 0) { if (is_integer(vexp)) { if (is_even(vexp)) { VpSetPosInf(y); } else { VpSetNegInf(y); } } else { /* TODO: support complex */ rb_raise(rb_eMathDomainError, "a non-integral exponent for a negative base"); } } else { VpSetPosInf(y); } return ToValue(y); } } if (exp != NULL) { return rmpd_power_by_big_decimal(x, exp, n); } else if (RB_TYPE_P(vexp, T_BIGNUM)) { VALUE abs_value = BigDecimal_abs(self); if (is_one(abs_value)) { return ToValue(VpCreateRbObject(n, "1")); } else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) { if (is_negative(vexp)) { y = VpCreateRbObject(n, "0#"); if (is_even(vexp)) { VpSetInf(y, VpGetSign(x)); } else { VpSetInf(y, -VpGetSign(x)); } return ToValue(y); } else if (VpGetSign(x) < 0 && is_even(vexp)) { return ToValue(VpCreateRbObject(n, "-0")); } else { return ToValue(VpCreateRbObject(n, "0")); } } else { if (is_positive(vexp)) { y = VpCreateRbObject(n, "0#"); if (is_even(vexp)) { VpSetInf(y, VpGetSign(x)); } else { VpSetInf(y, -VpGetSign(x)); } return ToValue(y); } else if (VpGetSign(x) < 0 && is_even(vexp)) { return ToValue(VpCreateRbObject(n, "-0")); } else { return ToValue(VpCreateRbObject(n, "0")); } } } int_exp = FIX2INT(vexp); ma = int_exp; if (ma < 0) ma = -ma; if (ma == 0) ma = 1; if (VpIsDef(x)) { mp = x->Prec * (VpBaseFig() + 1); GUARD_OBJ(y, VpCreateRbObject(mp * (ma + 1), "0")); } else { GUARD_OBJ(y, VpCreateRbObject(1, "0")); } VpPower(y, x, int_exp); return ToValue(y); }


