sawa
sawa

Reputation: 168189

Type casting in Fixnum ** Fixnum

In ruby-doc, it says that <Fixnum> ** <Numeric> may be fractional, and gives the examples:

2 ** -1 #=> 0.5
2 ** 0.5 #=> 1.4142135623731

but on my irb, it sometimes gives a Rational answer as with the exponent -1 below:

2 ** -1 #=> (1/2)
2 ** 0.5 #=> 1.4142135623731

It looks like ruby-doc is not accurate, and ruby tries to type cast to Rational when possible, but I am not completely sure. What is the exact type casting rule here when the base and the exponent are both Fixnum? I am particularly interested in Ruby 1.9.3, but is the result different among different versions?

Upvotes: 1

Views: 396

Answers (1)

Michelle Tilley
Michelle Tilley

Reputation: 159115

DGM is right; the answer is right in the docs you linked, although it's in C. Here is pertinent bit; I've added a few comments:

static VALUE
fix_pow(VALUE x, VALUE y)
{
    long a = FIX2LONG(x);

    if (FIXNUM_P(y)) {          // checks to see if Y is a Fixnum
        long b = FIX2LONG(y);

        if (b < 0)
            // if b is less than zero, convert x into a Rational
            // and call ** on it and 1 over y
            // (this is how you raise to a negative power).
            return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);

Now we can move on to the docs for Rational and check what it says about the ** operator:

rat ** numeric → numeric

Performs exponentiation.

For example:

Rational(2)    ** Rational(3)    #=> (8/1)
Rational(10)   ** -2             #=> (1/100)
Rational(10)   ** -2.0           #=> 0.01
Rational(-4)   ** Rational(1,2)  #=> (1.2246063538223773e-16+2.0i)
Rational(1, 2) ** 0              #=> (1/1)
Rational(1, 2) ** 0.0            #=> 1.0

Upvotes: 1

Related Questions