Bug #17318
closedRaising float to the power of other issue
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 > xy
=> (-0.48179173935576963+0.012409246172848264i)
2.6.3 :004 > -0.47905298330503080.9918032786885246
=> -0.4819515219418196
Updated by deXterbed (Manoj Mishra) about 4 years ago
Formatting replaced the double * with a single * i put in the snippet above, please ignore
Updated by mame (Yusuke Endoh) about 4 years ago
- 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)
Updated by deXterbed (Manoj Mishra) about 4 years ago
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
Updated by Dan0042 (Daniel DeLorme) about 4 years ago
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
Updated by mame (Yusuke Endoh) about 4 years ago
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
.
Updated by phluid61 (Matthew Kerwin) about 4 years ago
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.
Updated by gotoken (Kentaro Goto) about 4 years ago
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.