The following code fails to compile:
fn main() {
let x = (-5i32).abs();
let z: u32 = x;
}
with the message:
error[E0308]: mismatched types
--> src/main.rs:4:18
|
4 | let z: u32 = x;
| ^ expected u32, found i32
Reading the documentation, it looks the choice of i32
stems from the fact that i32::min_value()
has no positive representation in i32
. However, it would have a positive representation in u32
, which can represent numbers twice as large.
I'm learning the language, and want to understand why certain design decisions were made so that I can develop good habits. I find this one confusing. Can someone explain why it works this way instead of just returning a u32
, which would seem to be the semantically correct type?
Both can store 256 different values, but signed integers use half of their range for negative numbers, whereas unsigned integers can store positive numbers that are twice as large. An n-bit unsigned variable has a range of 0 to (2n)-1.
To convert a signed integer to an unsigned integer, or to convert an unsigned integer to a signed integer you need only use a cast. For example: int a = 6; unsigned int b; int c; b = (unsigned int)a; c = (int)b; Actually in many cases you can dispense with the cast.
A signed integer is a 32-bit datum that encodes an integer in the range [-2147483648 to 2147483647]. An unsigned integer is a 32-bit datum that encodes a nonnegative integer in the range [0 to 4294967295]. The signed integer is represented in twos complement notation.
In a C program, abs always takes and returns an int .
There's a link to the development meeting minutes where this was discussed in the proposed RFC "Change abs() to return unsigned integers"
It looks like the main reasons were:
i32
-> i32
(for instance, C, Java), because the accidental promotion of other values to u32
might cause bugs. Rust seems to have used i32
-> i32
for this reason originally (i.e. following convention), but doesn't suffer from the same kinds of bugs.It seems like the accepted workaround is to use as u32
to cast.
i32::overflowing_abs
i32::wrapping_abs
and i32::checked_abs
implement other solutions to the i32::min_value()
bug, but none of them produces a u32.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With