4

This leads to the situation like:

-1 ** 0.5 #=> -1

Only parenthesis remedies it:

(-1) ** 0.5 #=> 6.123031769111886e-17+1.0i

which is less favorable then expected 1.i, but basically acceptable. Before I go to Ruby bugs to complain, I would like to know whether there is perhaps some reason for this to be so?

sawa
  • 165,429
  • 45
  • 277
  • 381
Boris Stitnicky
  • 12,444
  • 5
  • 57
  • 74
  • I'm observing the same with Python. I don't know about other programming languages, but it doesn't seem to be Ruby-specific. – Tim Pietzcker Nov 11 '12 at 06:28
  • But it's insane, or is it just me? – Boris Stitnicky Nov 11 '12 at 06:28
  • 1
    Interestingly enough, it *is* a special case mentioned explicitly [in the Python docs](http://docs.python.org/2/reference/expressions.html#id28): unary `-` does have higher precedence than `**` on the RHS only. – Tim Pietzcker Nov 11 '12 at 06:31
  • Interesting. So at least Python devs seem to agree with me on this one issue. – Boris Stitnicky Nov 11 '12 at 06:40
  • 1
    Well, but only because there's no other way to parse `0.5 ** -1`. – Tim Pietzcker Nov 11 '12 at 06:42
  • @BorisStitnicky: It is higher when the unary `-` is the power, not the base. There isn't any other way of interpreting it. – Tim Nov 11 '12 at 06:42
  • :-( that one works in Ruby, too: `0.5 ** -1 #=> 2`, as expected. But I'd really like it to bind more tightly on the LHS, too... – Boris Stitnicky Nov 11 '12 at 06:43
  • I've created [a Ruby issue for this](http://bugs.ruby-lang.org/issues/7328). Let's see what they say when rejecting it. – Boris Stitnicky Nov 11 '12 at 07:02
  • I think whichever way you cut it, someone will be surprised it wasn't the other way around – Frederick Cheung Nov 11 '12 at 08:47
  • 1
    That is the way it is in mathematics. – sawa Nov 11 '12 at 09:48
  • 1
    @sawa: You mean like `-n²`? But that looks totally different than `-2 ** 2`. – Boris Stitnicky Nov 11 '12 at 11:58
  • 1
    @BorisStitnicky That is what it is. Knuth notation for power is to use either `↑` or `^` instead of superscript: `-n^2`. In programming, this power `^` is expressed as `**`. In all the notational variants, the strength of the associativity is the same. – sawa Nov 11 '12 at 12:14
  • @sawa: Thanks, Matz rationalized the `**` precedence in the same way (mathematics). This behavior goes against mine and many others' intuition, but as long as it is wanted and rationalized, I am satisfied and can simply memorize it for use. – Boris Stitnicky Nov 12 '12 at 02:55

2 Answers2

6

Many languages define their operator precedence tables by modeling after mathematics' order of operations. In math, exponentiation does have higher precedence than multiplication, and unary negation is a multiplication, after all.

From matz in a reply to "the sign of a number is omitted when squaring it":

People with mathematical background demands precedence for ** being higher than that of unary minus. That's the reason.

Platinum Azure
  • 45,269
  • 12
  • 110
  • 134
  • I apologize, but I cannot agree with this rationalization. I would accept it if you provide a link to where Matz says so. Multiplication in the strict sense is defined by '*'. Unary '-' is negation, distinct from both multiplication and subtraction. – Boris Stitnicky Nov 11 '12 at 06:34
  • 1
    Also, from the algebra point of view, negation does not even require multiplication to be defined. It simply requires that addition is defined, and that a + negated_a = 0. – Boris Stitnicky Nov 11 '12 at 07:01
  • 1
    If Ruby would have been modelled after math it would have been the other way around. Today, "-1 squared" (-1 ** 2) yields -1, not 1 which is the natural mathematical result, as Ruby parses this "-(1 squared)". – Lindydancer Nov 11 '12 at 07:35
  • @pst: Thanks for the link, that's what I was after. – Boris Stitnicky Nov 12 '12 at 02:51
4

Yes, ** has a higher precedence in Ruby.

Unlike some languages, - is not lex'ed as part of the number literal and is thus just (and universally) the unary - (aka -@). That is, both -x and -1 parse the unary -@ as an operator applied to the result of the expression.

  • Thanks, this is helpful, but I already knew that. I am having problem with `**` having higher binding force (ie. precedence) than `-@`, and I am asking whether this has been rationalized by Matz somewhere, or I am free to complain about it. – Boris Stitnicky Nov 11 '12 at 06:36
  • Let's wait whether anyone knows anything more on this. – Boris Stitnicky Nov 11 '12 at 06:41
  • @BorisStitnicky I updated Platinum's answer with the forum link he found. I think that answers the "why" bit from Matz's view. –  Nov 11 '12 at 18:51