5

I've been using the pow() method on integers. I tried raising a u32 to a negative power, which resulted in an compile error.

fn main() {
    println!("{}", 2u32.pow(-1));
}
error[E0600]: cannot apply unary operator `-` to type `u32`
 --> src/main.rs:2:29
  |
2 |     println!("{}", 2u32.pow(-1));
  |                             ^^

This makes perfect sense, because the pow() function does not take a signed integer as a parameter.

Is there any way to raise an integer to a signed integer power, ideally without using an experimental nightly API? Is there any reason to only allow for unsigned integers as parameters to the pow() function?

I expect that the result would be 0.5, and the type would be a float. I now see that a function which allows for this probably cannot be called directly on the unsigned integer, because that would result in its type changing.

Perhaps there is a function which then takes both the base and power as an argument and returns a float, if such a function cannot be called directly on the integer?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Micheal O'Dwyer
  • 1,237
  • 1
  • 16
  • 26
  • The problem is you're raising an unsigned integer to a signed power. – jhpratt Jul 30 '18 at 22:16
  • 2
    The float class of numbers have `powi`: https://play.rust-lang.org/?gist=e6e34ab56425d0456cb8165b520c9e56&version=stable&mode=debug&edition=2015 – squiguy Jul 30 '18 at 23:25
  • Apologies, I meant to ask if I can raise an unsigned integer to a *signed* integer. (I used the word integer in a mathematical sense.) I see that float numbers have `powi`, is there any similar function for unsigned integers? – Micheal O'Dwyer Jul 30 '18 at 23:53
  • *I used the word integer in a mathematical sense* — ["An integer (from the Latin integer meaning "whole") is a number that can be written without a fractional component. **For example, 21, 4, 0, and −2048 are integers**"](https://en.wikipedia.org/wiki/Integer) – Shepmaster Jul 31 '18 at 00:18
  • 1
    Note that in computer hardware you can't raise an integer to an integer power and get a floating point output -- if you want a floating-point result, you have to convert (one of) the inputs to floating point and feed them into the appropriate piece of hardware. When languages like Perl or Javascript tell you that `1 / 2` is `0.5`, they're implicitly using floating-point numbers under the hood, even if they behave like integers otherwise. Rust forgoes that slight convenience in favor of making you *tell* it exactly what kind of floating-point math you want. – trent Jul 31 '18 at 02:15
  • 1
    Note that Rust generally doesn't convert types automatically, unlike most other languages. So you have to tell it explicitly, using a cast or `from()`. – starblue Jul 31 '18 at 05:35
  • Thanks for clarifying the underlying hardware process @trentcl! Yeah, it makes sense why this function doesn't exist, as it isn't really possible without implicit numerical casting. – Micheal O'Dwyer Jul 31 '18 at 12:40

1 Answers1

6

I expect that the result [...] type would be a float

There is no float type in Rust. If you refer back to The Rust Programming Language, specifically the chapter on data types, you'll see that there are two built-in floating point types: f32 and f64. Which of those should this proposed method return?

I expect that the result would be 0.5

(2u32 as f32).powi(-1)
(2u32 as f64).powi(-1)

if such a function cannot be called directly on the integer

Any method can be called as a function:

f32::powi(2u32 as f32, -1)
f64::powi(2u32 as f64, -1)

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Thanks for the answer! I realized that the method I was looking for isn't exactly needed, as one exists for f32s or f64. Calling methods as functions is something I never knew about. Very helpful! – Micheal O'Dwyer Jul 31 '18 at 01:25
  • The first sentence not only is false, unless you mean that there's a type that is called `float`, which one could also define and so exist, but it seems to be in contradiction with "there are two built-in floating point types". Clearly, the term "float" is a short for "floating-point number". So, in my view, you should remove the statement "There is no float type in Rust.", which is misleading. – nbro Jan 08 '23 at 21:31
  • @nbro “There is no `float` type in Rust” (with the code syntax) indicates that there’s no type called `float` defined by the Rust language (in contrast to C or C++, for example). This is a true statement, so I don’t understand your point. – Shepmaster Jan 08 '23 at 21:40
  • @Shepmaster My point is that statement can be interpreted in two ways. One of the interpretations is wrong, the other is correct. So, maybe you can be more explicit and say that "floating-point numbers exist in Rust but they are not called `float` but `f32`, etc". I don't think this was the doubt of the OP. – nbro Jan 08 '23 at 21:43