https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112020-03-07T13:22:41ZRuby Issue Tracking SystemRuby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845312020-03-07T13:22:41ZCamilleDrapier (Camille Drapier)
<ul></ul><p>Oh sorry, I just notice that this is an expected behaviour in the documentation (example) given in Integer.</p>
<p>I guess the to-i attribute assignment is a bit confusing that it changes the behaviour but probably not a bug!</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845332020-03-07T14:25:07ZEregon (Benoit Daloze)
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>This is just operator precedence, ** has higher precedence than unary minus.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845342020-03-07T16:25:27ZDan0042 (Daniel DeLorme)
<ul></ul><p>It's actually a bit more complicated than that.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">-</span><span class="mi">2</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">**</span> <span class="mf">2.2</span> <span class="c1">#=> (3.717265962412589+2.7007518095995264i)</span>
<span class="n">x</span> <span class="o">=</span> <span class="mi">2</span>
<span class="o">-</span><span class="n">x</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">**</span> <span class="mf">2.2</span> <span class="c1">#=> -4.59479341998814</span>
</code></pre>
<p>So it looks like there's something special about how negative integers are parsed? I'm not really sure how to describe the above behavior.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845352020-03-07T16:55:47Zsawa (Tsuyoshi Sawada)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/84535/diff?detail_id=56548">diff</a>)</li></ul> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845362020-03-07T16:56:06Zsawa (Tsuyoshi Sawada)
<ul><li><strong>Status</strong> changed from <i>Closed</i> to <i>Open</i></li></ul> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845382020-03-07T17:04:13Zsawa (Tsuyoshi Sawada)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/84538/diff?detail_id=56550">diff</a>)</li></ul> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845392020-03-07T17:05:23Zalanwu (Alan Wu)
<ul></ul><blockquote>
<p>So it looks like there's something special about how negative integers are parsed?</p>
</blockquote>
<p>Negative integers are atomic tokens whereas the expression <code>-x</code> applies the unary <code>-</code> operator to <code>x</code>.</p>
<p><code>-x.to_i</code> is parsed as <code>-(x.to_i)</code>:</p>
<pre><code>$ ruby --dump=parsetree -e '-x.to_i'
###########################################################
## Do NOT use this node dump for any purpose other than ##
## debug and research. Compatibility is not guaranteed. ##
###########################################################
# @ NODE_SCOPE (line: 1, location: (1,0)-(1,7))
# +- nd_tbl: (empty)
# +- nd_args:
# | (null node)
# +- nd_body:
# @ NODE_OPCALL (line: 1, location: (1,0)-(1,7))*
# +- nd_mid: :-@
# +- nd_recv:
# | @ NODE_CALL (line: 1, location: (1,1)-(1,7))
# | +- nd_mid: :to_i
# | +- nd_recv:
# | | @ NODE_VCALL (line: 1, location: (1,1)-(1,2))
# | | +- nd_mid: :x
# | +- nd_args:
# | (null node)
# +- nd_args:
# (null node)
</code></pre>
<p>while <code>-2.to_i</code> is parsed as <code>(-2).to_i</code>. I guess it's the typical "things that look the same are not always the same" thing in programming languages :)<br>
Side note, it's a bit surprising to me that <a href="https://ruby-doc.org/core-2.7.0/doc/syntax/precedence_rdoc.html" class="external">the doc for operator precedence</a> does not mention the method call operator (the dot), but I suppose it's not really an operator?</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845412020-03-07T18:12:52ZDan0042 (Daniel DeLorme)
<ul></ul><blockquote>
<p>Negative integers are atomic tokens</p>
</blockquote>
<p>If that was the case then <code>-2 ** 2.2</code> would be parsed as <code>(-2) ** 2.2</code>, which is not the case as shown above.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845452020-03-07T23:40:30Zalanwu (Alan Wu)
<ul></ul><p>Ah thanks for catching that.<br>
Interesting, <code>-2 ** 2.2</code> is parsed as <code>-(2 ** 2.2)</code> whereas <code>-2.to_i ** 2.2</code> is parsed as <code>((-2).to_i) ** 2.2</code>.<br>
It looks like whether it is a literal of negative two changes depending on the presence of the method call.<br>
<code>-2</code> and <code>-2.to_i</code> look so similar on paper!</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=845472020-03-08T12:20:10ZEregon (Benoit Daloze)
<ul></ul><p>It seems rather unexpected that <code>-2 ** 2.2</code> is parsed as <code>-(2 ** 2.2)</code>, I would expect <code>(-2) ** 2.2</code> as well.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=846022020-03-12T00:50:48Zmrkn (Kenta Murata)muraken@gmail.com
<ul><li><strong>Assignee</strong> set to <i>matz (Yukihiro Matsumoto)</i></li></ul><p>I also expect <code>(-2) ** 2.2</code> rather than <code>-(2 ** 2.2)</code>.</p>
<p>How you think, <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/13">@matz (Yukihiro Matsumoto)</a>?</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=846032020-03-12T01:14:30Zmrkn (Kenta Murata)muraken@gmail.com
<ul></ul><blockquote>
<p>I also expect <code>(-2) ** 2.2</code> rather than <code>-(2 ** 2.2)</code>.</p>
</blockquote>
<p>Sorry, I reversed each of them. I expect the current behavior, that is <code>-(2 ** 2.2)</code>, rather than <code>(-2) ** 2.2</code>.<br>
The current interpretation seems to follow the rule we use for writing equations down by our hands.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=846042020-03-12T06:30:41ZAnonymous
<ul></ul><p>As far as I know there is no strictly correct math rule for evaluating <code>-2 ** 2.2</code> to <code>-(2 ** 2.2)</code> or <code>(-2) ** 2.2</code>. I expect the current behavior <code>-(2 ** 2.2)</code> since I think exponentiation takes higher precedence than unary minus operation.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=846062020-03-12T18:04:42ZDan0042 (Daniel DeLorme)
<ul></ul><p>In math exponentation is expressed as superscript; there's no exponentation "operator" per se, afaik. So <code>-2²</code> is <code>-(2²)</code> according to mathematical rules, and it feels quite obvious to me. It doesn't feel quite as right when written with an operator though; <code>-2**2</code> doesn't have that same obviousness, and <code>-2 ** 2</code> is downright deceptive.</p>
<p>But a quick search in gems shows things like <code>Time.at(-2**63)</code> where it's clearly intended as <code>-(2**63)</code>. I think those precedence rules are ok, especially given that most languages work the same way (see table below). But in that case <code>-2.to_i ** 2</code> should obey expected rules and parse as <code>-(2.to_i ** 2)</code>. Although a quick search in gems shows a few things like <code>-28.upto(28)</code> or <code>-5.hash</code> that would break (mostly in tests/specs).</p>
<p>For reference, here's some other languages' precedence rules for exponentation and unary operators: (from high to low precedence)</p>
<table>
<thead>
<tr>
<th>language</th>
<th></th>
<th>exp.</th>
<th></th>
<th></th>
<th>note</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ruby</td>
<td>! ~ +</td>
<td>**</td>
<td>-</td>
<td></td>
<td>quite unique...</td>
</tr>
<tr>
<td>Perl</td>
<td></td>
<td>**</td>
<td>! ~ \ + -</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Python</td>
<td></td>
<td>**</td>
<td>~</td>
<td>+ -</td>
<td></td>
</tr>
<tr>
<td>Javascript</td>
<td>! ~ + -</td>
<td>**</td>
<td></td>
<td></td>
<td>but <code>-2**2</code> is a SyntaxError</td>
</tr>
<tr>
<td>F#</td>
<td>+ -</td>
<td>**</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Excel, Basic</td>
<td>+ -</td>
<td>^</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Lua</td>
<td></td>
<td>^</td>
<td>-</td>
<td></td>
<td></td>
</tr>
<tr>
<td>R</td>
<td></td>
<td>^</td>
<td>+ -</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p>I kinda like how Javascript does it; just force people to use parentheses! :-)</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=846082020-03-12T23:36:06Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>Dan0042 (Daniel DeLorme) wrote in <a href="#note-14">#note-14</a>:</p>
<blockquote>
<p>But a quick search in gems shows things like <code>Time.at(-2**63)</code> where it's clearly intended as <code>-(2**63)</code>. I think those precedence rules are ok, especially given that most languages work the same way (see table below). But in that case <code>-2.to_i ** 2</code> should obey expected rules and parse as <code>-(2.to_i ** 2)</code>. Although a quick search in gems shows a few things like <code>-28.upto(28)</code> or <code>-5.hash</code> that would break (mostly in tests/specs).</p>
</blockquote>
<p>Very good point. The current behavior is indeed a bit inconsistent, but reasonable. I vote for no change to keep the compatibility.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=846092020-03-13T02:19:30Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul><li><strong>Is duplicate of</strong> <i><a class="issue tracker-1 status-6 priority-4 priority-default closed" href="/issues/13152">Bug #13152</a>: Numeric parsing differences between ruby <-> crystal</i> added</li></ul> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=846122020-03-13T09:19:40Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>I vote for keeping precedence, for compatibility's sake. All other things (e.g. consistency between languages) are trivial.</p>
<p>Matz.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=846482020-03-15T03:02:11ZDan0042 (Daniel DeLorme)
<ul></ul><p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/13">@matz (Yukihiro Matsumoto)</a>,<br>
I find your statement a bit confusing. You vote for "keeping precedence" but the entire point of this bug report is that <code>-2.to_i ** 2.2</code> does <em>not</em> respect the precedence rules. For example <code>-2.to_s</code> results in "-2" rather than frozen "2". So did you mean that we should keep the current inconsistent behavior, or fix it to always follow precedence rules?</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=846492020-03-15T04:59:52Zsawa (Tsuyoshi Sawada)
<ul></ul><p>The most confusing part of the current behaviour is that (it superficially looks like) the precedence relation between the three operations (i) <code>-</code>, (ii) typical method call (using a period), and (iii) <code>**</code> does not follow transitivity, but is rather in a rock-paper-scissors relation.</p>
<p>(a) <code>-</code> has priority over a typical method call: <code>-2.itself # => (-2).itself</code>,<br>
(b) a typical method call has priority over <code>**</code>: <code>2.itself ** 2 # => (2.itself) ** 2</code>, and yet<br>
(c) <code>**</code> has priority over <code>-</code>: <code>-2 ** 2 # => -(2 ** 2)</code></p>
<p>After close examination, we can tell that this is only superficial, and actually not due to precedence relation. (a) is due to the fact that <code>-</code> as a part of a literal works differently from the unary method <code>-@</code>. (b) is due to the fact that <code>2.(itself ** 2)</code> does not make sense.</p>
<p>What is problematic is that we have to do close examination whenever we get lost using them. (b) is inevitable, and (c) matches our convention in mathematics. What has room of improvement is (a).</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=854042020-05-07T03:22:47Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/11019">@Dan0042 (Daniel DeLorme)</a> To rephrase, I vote for changing nothing, keeping the current behavior. It may be inconsistent but not worth breaking existing code.</p>
<p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/2963">@sawa (Tsuyoshi Sawada)</a> Are you proposing something new? I couldn't read the concrete behavior proposed.</p>
<p>Matz.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=854052020-05-07T05:26:09Zsawa (Tsuyoshi Sawada)
<ul></ul><p>matz (Yukihiro Matsumoto) wrote in <a href="#note-20">#note-20</a>:</p>
<blockquote>
<p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/2963">@sawa (Tsuyoshi Sawada)</a> Are you proposing something new? I couldn't read the concrete behavior proposed.</p>
</blockquote>
<p>My proposal (which I have suggested not so clearly in my previous comment) is this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">-</span><span class="mi">2</span><span class="p">.</span><span class="nf">itself</span> <span class="c1"># => -(2.itself) (change from current behavior)</span>
</code></pre>
<p>From this, it follows that:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">-</span><span class="mi">2</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">**</span> <span class="mf">2.2</span> <span class="c1"># => -(2.to_i ** 2.2) (change from current behavior)</span>
<span class="o">-</span><span class="mi">2</span><span class="p">.</span><span class="nf">to_s</span> <span class="c1"># => frozen "2" (change from current behavior)</span>
</code></pre> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=854072020-05-07T05:38:01Zsawa (Tsuyoshi Sawada)
<ul></ul><p>As an argument for this proposal, unary operators like <code>-@</code> and <code>+@</code> look very similar to splat operators <code>*</code>, <code>**</code>, and <code>&</code> in the sense that they are located at the front-most position of an expression. Since the splat operators have the lowest operator precedence, it is natural for Ruby users to assume that that also applies to unary operators.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=854262020-05-07T14:01:16Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>sawa (Tsuyoshi Sawada) wrote in <a href="#note-21">#note-21</a>:</p>
<blockquote>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">-</span><span class="mi">2</span><span class="p">.</span><span class="nf">itself</span> <span class="c1"># => -(2.itself) (change from current behavior)</span>
<span class="o">-</span><span class="mi">2</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">**</span> <span class="mf">2.2</span> <span class="c1"># => -(2.to_i ** 2.2) (change from current behavior)</span>
<span class="o">-</span><span class="mi">2</span><span class="p">.</span><span class="nf">to_s</span> <span class="c1"># => frozen "2" (change from current behavior)</span>
</code></pre>
</blockquote>
<p>A space after <code>-</code> means same things.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=854582020-05-08T14:53:08ZDan0042 (Daniel DeLorme)
<ul></ul><p>nobu (Nobuyoshi Nakada) wrote in <a href="#note-23">#note-23</a>:</p>
<blockquote>
<p>A space after <code>-</code> means same things.</p>
</blockquote>
<p>Wow! So <code>-2.to_s</code> is different from <code>- 2.to_s</code> !?!?!<br>
I find this really amazing. I'm just not sure if it's amazing in a good or a bad way.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=854602020-05-08T16:04:04Zsawa (Tsuyoshi Sawada)
<ul></ul><p>nobu (Nobuyoshi Nakada) wrote in <a href="#note-23">#note-23</a>:</p>
<blockquote>
<p>A space after <code>-</code> means same things.</p>
</blockquote>
<p>Thank you for the information. That further strengthens the motivation for the proposal.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=854652020-05-09T07:08:49Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>sawa (Tsuyoshi Sawada) wrote in <a href="#note-25">#note-25</a>:</p>
<blockquote>
<blockquote>
<p>A space after <code>-</code> means same things.</p>
</blockquote>
<p>Thank you for the information. That further strengthens the motivation for the proposal.</p>
</blockquote>
<p>Really?<br>
It feels counter-motivation to me.</p> Ruby master - Bug #16677: Negative integer powered (**) to a float number results in a complex https://redmine.ruby-lang.org/issues/16677?journal_id=938262021-09-24T01:01:09Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul><li><strong>Has duplicate</strong> <i><a class="issue tracker-1 status-6 priority-4 priority-default closed" href="/issues/18188">Bug #18188</a>: -1 ** 0 is 1 not -1</i> added</li></ul>