Skip to content

Casts between floats and ints fail to roundtrip properly on i586-unknown-linux-gnu #152635

@okaneco

Description

@okaneco

Doc tests introduced in #152512 for f32 and f64 failed in a rollup #152616 (comment) on the i586-unknown-linux-gnu job.

These tests as cast between i32<->f32 and i64<->f64, with no floating point arithmetic performed.

I tried this code:

{ // Max exact integer test, f32
let max_exact_int: i32 = (1 << f32::MANTISSA_DIGITS) - 1;
assert_eq!(max_exact_int, max_exact_int as f32 as i32);
assert_eq!(max_exact_int + 1, (max_exact_int + 1) as f32 as i32);
assert_ne!(max_exact_int + 2, (max_exact_int + 2) as f32 as i32);
// Beyond `f32::MAX_EXACT_INTEGER`, multiple integers can map to one float value
assert_eq!((max_exact_int + 1) as f32, (max_exact_int + 2) as f32);
}

{ // Min exact integer test, f32
let min_exact_int: i32 = -((1 << f32::MANTISSA_DIGITS) - 1);
assert_eq!(min_exact_int, min_exact_int as f32 as i32);
assert_eq!(min_exact_int - 1, (min_exact_int - 1) as f32 as i32);
assert_ne!(min_exact_int - 2, (min_exact_int - 2) as f32 as i32);
// Below `f32::MIN_EXACT_INTEGER`, multiple integers can map to one float value
assert_eq!((min_exact_int - 1) as f32, (min_exact_int - 2) as f32);
}

{ // Max exact integer test, f64
let max_exact_int: i64 = (1 << f64::MANTISSA_DIGITS) - 1;
assert_eq!(max_exact_int, max_exact_int as f64 as i64);
assert_eq!(max_exact_int + 1, (max_exact_int + 1) as f64 as i64);
assert_ne!(max_exact_int + 2, (max_exact_int + 2) as f64 as i64);
// Beyond `f64::MAX_EXACT_INTEGER`, multiple integers can map to one float value
assert_eq!((max_exact_int + 1) as f64, (max_exact_int + 2) as f64);
}

{ // Min exact integer test, f64
let min_exact_int: i64 = -((1 << f64::MANTISSA_DIGITS) - 1);
assert_eq!(min_exact_int, min_exact_int as f64 as i64);
assert_eq!(min_exact_int - 1, (min_exact_int - 1) as f64 as i64);
assert_ne!(min_exact_int - 2, (min_exact_int - 2) as f64 as i64);
// Below `f64::MIN_EXACT_INTEGER`, multiple integers can map to one float value
assert_eq!((min_exact_int - 1) as f64, (min_exact_int - 2) as f64);
}

I expected to see this happen: All 4 of these test blocks should pass

Instead, this happened: All 4 blocks failed

Probably related to #114479

Meta

I didn't see the toolchain in the log, but whatever tip of nightly was at 2026-02-14T16:31:07.2087585Z

Backtrace

---
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:80:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<i32, i32>
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:394:5
   4: rust_out::main::_doctest_main_library_core_src_num_f32_rs_528_0
   5: rust_out::main
   6: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- library/core/src/num/f32.rs - f32::f32::MAX_EXACT_INTEGER (line 528) stdout end ----
---
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:80:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<i32, i32>
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:394:5
   4: rust_out::main::_doctest_main_library_core_src_num_f32_rs_555_0
   5: rust_out::main
   6: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- library/core/src/num/f32.rs - f32::f32::MIN_EXACT_INTEGER (line 555) stdout end ----
---
   1: core::panicking::panic_fmt
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:80:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<i64, i64>
   4: rust_out::main::_doctest_main_library_core_src_num_f64_rs_527_0
   5: rust_out::main
   6: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- library/core/src/num/f64.rs - f64::f64::MAX_EXACT_INTEGER (line 527) stdout end ----
---
   1: core::panicking::panic_fmt
             at /rustc/b184b22b186f12ce7b538c7857b49650d492a1fc/library/core/src/panicking.rs:80:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<i64, i64>
   4: rust_out::main::_doctest_main_library_core_src_num_f64_rs_554_0
   5: rust_out::main
   6: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- library/core/src/num/f64.rs - f64::f64::MIN_EXACT_INTEGER (line 554) stdout end ----

@rustbot label A-floating-point O-x86_32

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-floating-pointArea: Floating point numbers and arithmeticC-bugCategory: This is a bug.O-x86_32Target: x86 processors, 32 bit (like i686-*) (also known as IA-32, i386, i586, i686)needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions