## Bug #17318

closed
### Raising float to the power of other issue

Added by deXterbed (Manoj Mishra) about 1 year ago.
Updated about 1 year ago.

**Description**

Raising a negative float to another float results in a complex number. Interestingly, doing the same thing without using variables works fine!

Sample Snippet:

$ irb

2.6.3 :001 > x=-0.4790529833050308

=> -0.4790529833050308

2.6.3 :002 > y=0.9918032786885246

=> 0.9918032786885246

2.6.3 :003 > x**y*

=> (-0.48179173935576963+0.012409246172848264i)

2.6.3 :004 > -0.4790529833050308*0.9918032786885246

=> -0.4819515219418196

Formatting replaced the double * with a single * i put in the snippet above, please ignore

**Status** changed from *Open* to *Rejected*

It is due to precedence of operators unary minus and `**`

.

`x**y`

calculates `(-0.4790529833050308)**0.9918032786885246`

, and `-0.4790529833050308**0.9918032786885246`

calculates `-(0.4790529833050308**0.9918032786885246)`

.

irb(main):001:0> -(0.4790529833050308**0.9918032786885246)
=> -0.4819515219418196
irb(main):002:0> (-0.4790529833050308)**0.9918032786885246
=> (-0.48179173935576963+0.012409246172848266i)

mame (Yusuke Endoh) wrote in #note-2:

It is due to precedence of operators unary minus and `**`

.

`x**y`

calculates `(-0.4790529833050308)**0.9918032786885246`

, and `-0.4790529833050308**0.9918032786885246`

calculates `-(0.4790529833050308**0.9918032786885246)`

.

irb(main):001:0> -(0.4790529833050308**0.9918032786885246)
=> -0.4819515219418196
irb(main):002:0> (-0.4790529833050308)**0.9918032786885246
=> (-0.48179173935576963+0.012409246172848266i)

Thanks for the explanation Yusuke Endoh,

that still raises the question, how exactly am i supposed to calculate x**y without ending up with a complex number? x and y are dynamic values, i can't use parentheses to force precedence. I could use "abs" method but shouldn't this be the default behaviour?

def raise(a, b)
return -((a.abs)**b) if a < 0
a**b
end

Also see #16677 w/r edge cases.

-0.4**0.9 #=> -0.4383832905540869
-0.4.to_f**0.9 #=> (-0.416927285116376+0.13546788683122327i)
-(0.4).to_f**0.9 #=> -0.4383832905540869

deXterbed (Manoj Mishra) wrote in #note-3:

def raise(a, b)
return -((a.abs)**b) if a < 0
a**b
end

I don't think that this should be the default behavior because `raise(-1, 2)`

returns `-1`

but I expect the square of `-1`

to be `1`

.

deXterbed (Manoj Mishra) wrote in #note-3:

that still raises the question, how exactly am i supposed to calculate x**y without ending up with a complex number?

Don't raise a negative number to a non-Integer power. That's just maths.

That depends on your purpose or background of the problem. In non-math situations, `power(a, b)`

should not return any ordinary number for given `a`

<0 where `power(a, b)`

stands for "`a`

to the power of `b`

" over real, just identical to your notation `raise(a, b)`

. In such cases, so the function may raise an exception or returns `float::NAN`

if `a<0`

or `a==0 && b==0`

held.

Also available in: Atom
PDF