Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Peculiar behavior with -1 and pow

I was debugging some code to compute the determinant of a matrix, and was sorely disappointed when I found the cause. Simply put, this code:

-1i64.pow(i as u32)

always results in -1. I found that I could use i64::pow instead, or wrap -1i64 in parentheses to solve the issue:

i64::pow(-1, i as u32)
(-1i64).pow(-1, i as u32)

I’m disappointed and sad-mad because rustc told me to use the first example:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  |
3 |         println!("{}", -1.pow(i as u32));
  |                              ^^^
  |
help: you must specify a concrete type for this numeric value, like `i32`
  |
3 |         println!("{}", -1_i32.pow(i as u32));
  |                            ~~~~~

I tried with and without the underscore and they both still always result in -1. My question is, why is this the case? What purpose do the parentheses serve here? What does -1i64.pow(i as u32) actually do? I could not find anything in the documentation, Rust book, or Stack Overflow.

Here’s a playground

>Solution :

Your code parses as -(1.pow(...)). 1.pow(...) is 1. Negating 1 produces -1. Parentheses change precedence, as usual, so pow is sent to -1, not 1.

I’m disappointed and sad-mad because rustc told me to use the first example:

Rust does not know whether you want to negate 1 or 1.pow(...), so your disappointment is displaced 😛


Addendum regarding JavaScript:

Of course you can call methods on numbers; but JavaScript will complain if you do it on 1 because it will always expect the first dot to be the decimal dot, so if calling methods directly on number literals you have to make them float (i.e. 1.toString() is bad, 1.0.toString() is good, as are (1).toString() and 1..toString()).

Now, Number doesn’t have a method pow, but we can make it:

Number.prototype.pow = function(p) { return Math.pow(this, p) }

Now you have the same situation as in Rust:

-1.0.pow(2)
# => -1
(-1.0).pow(2)
# => 1
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading