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:
|
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.
>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