Bug #17318
closed
Raising float to the power of other issue
Added by deXterbed (Manoj Mishra) about 4 years ago.
Updated about 4 years 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 > xy
=> (-0.48179173935576963+0.012409246172848264i)
2.6.3 :004 > -0.47905298330503080.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
Like0
Like0Like0Like0Like0Like0Like0Like0