Description
I encountered 'arithmetic operation overflowed' panick when calling std::i32::MIN.abs() and similarly for i8, i16, and i64.
The docs for 1.0.0-beta.5 std::num abs function says:
Int::min_value() will be returned if the number is Int::min_value().
I suspect && self != <$T>::min_value()
is needed in the if
condition for the block that returns "!self + 1" inabs
implementation such as:
pub fn abs(self) -> $T {
if self.is_negative() && self != $T::min_value() {
!self + 1 // wrapping_neg
} else {
self
}
}
I tried this code:
fn main() {
println!("{}", (std::i8::MIN).abs()); // Expected i8::MIN
println!("{}", (std::i16::MIN).abs()); // Expected i16::MIN
println!("{}", (std::i32::MIN).abs()); // Expected i32::MIN
println!("{}", (std::i64::MIN).abs()); // Expected i64::MIN
}
I expected to see this happen:
-128
-32768
-2147483648
-9223372036854775808
Instead, this happened:
thread '<main>' panicked at 'arithmetic operation overflowed', /tmp/build/rustc-1.0.0-beta.5/src/libcore/num/mod.rs:509
Meta
rustc --version --verbose
:
rustc 1.0.0-dev (built 2015-05-13)
binary: rustc
commit-hash: unknown
commit-date: unknown
build-date: 2015-05-13
host: x86_64-unknown-linux-gnu
release: 1.0.0-dev
$ RUST_BACKTRACE=1 ./try_abs2
thread '<main>' panicked at 'arithmetic operation overflowed', /tmp/build/rustc-1.0.0-beta.5/src/libcore/num/mod.rs:509
stack backtrace:
1: 0x7f181b0a98f9 - sys::backtrace::write::he573c8167e01081cd4r
2: 0x7f181b0acab8 - panicking::on_panic::had2e9609e9ec19cdjrw
3: 0x7f181b0a5f32 - rt::unwind::begin_unwind_inner::h2b37885f8310bdebt6v
4: 0x7f181b0a61ec - rt::unwind::begin_unwind_fmt::h8504c97e3506491474v
5: 0x7f181b0ac426 - rust_begin_unwind
6: 0x7f181b0d5094 - panicking::panic_fmt::hdf7ef67474c35dd3wwy
7: 0x7f181b0d5014 - panicking::panic::hf43ff458bd7d8b953uy
8: 0x7f181b0a470d - num::i8::abs::h3652d8ae9a3c4a64Qhc
9: 0x7f181b0a432b - main::h50fc8aac82f30ec4eaa
10: 0x7f181b0b0a48 - rust_try_inner
11: 0x7f181b0b0a35 - rust_try
12: 0x7f181b0ae20b - rt::lang_start::hed504002616c7361Olw
13: 0x7f181b0a4b7e - main
14: 0x7f181a29daf4 - __libc_start_main
15: 0x7f181b0a41d8 - <unknown>
16: 0x0 - <unknown>
As a side-node, I tried this with C (gcc 4.8.3) on the same platform (CentOS 7 x86_64) and abs(INT_MIN) returns INT_MIN, and labs(LONG_MIN) returns LONG_MIN in case there is question whether Rust's documented behavior of abs() returning Int::min_value() is consistent with common C/C++ library implementation (and it is).
Disclaimer: This is C code:
printf("%d %d\n", INT_MIN, abs(INT_MIN));
printf("%ld %ld\n", LONG_MIN, labs(LONG_MIN));
Output:
-2147483648 -2147483648
-9223372036854775808 -9223372036854775808