makepad/libs/relax/compiler/tests/wide_float_cast.rs
Admin b22a714840 makepad run: the Rust JIT (libs/relax) and makepad-remote
The JIT that runs makepad apps from source: lexer, front end, type checker,
lazy borrow checker (Gandalf; `--check-first` opts in), codegen, session and
warm/cold caches keyed by compiler stamp, provided crates bound late,
startup images, live patching. User-facing name is `makepad run` (binary
`makepad`, MAKEPAD_RUN_* env, ~/.makepad-run); libs/relax stays the internal
library name. `makepad check` reports rustc-style diagnostics with rustc
error codes and checks a whole workspace (`--workspace`). Runs on macOS,
Linux, Windows and Android. makepad-remote: one tool schema for apps and the
WM (app/1): grabs, captures, traces, frame profiles and tweaks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:26:21 +02:00

64 lines
2.4 KiB
Rust

// Integer-to-float casts round the complete value once, including negative
// values whose two's-complement halves would cancel if converted separately.
#[inline(never)]
fn signed64(value: i128) -> f64 { value as f64 }
#[inline(never)]
fn unsigned64(value: u128) -> f64 { value as f64 }
#[inline(never)]
fn signed32(value: i128) -> f32 { value as f32 }
#[inline(never)]
fn unsigned32(value: u128) -> f32 { value as f32 }
#[test]
fn small_signed_values() {
for value in [-97500i64, -65000, -2500, -25, -1, 0, 1, 2500, 97500] {
assert_eq!(signed64(value as i128).to_bits(), (value as f64).to_bits());
assert_eq!(signed32(value as i128).to_bits(), (value as f32).to_bits());
}
}
#[test]
fn unsigned_double_precision_rounding() {
let base = 1u128 << 127;
let half = 1u128 << 74;
let bits = 1150u64 << 52;
assert_eq!(unsigned64(base + half - 1).to_bits(), bits);
assert_eq!(unsigned64(base + half).to_bits(), bits);
assert_eq!(unsigned64(base + half + 1).to_bits(), bits + 1);
assert_eq!(unsigned64(u128::MAX).to_bits(), 1151u64 << 52);
}
#[test]
fn signed_double_precision_rounding() {
let base = 1i128 << 126;
let half = 1i128 << 73;
let bits = 1149u64 << 52;
assert_eq!(signed64(base + half + 1).to_bits(), bits + 1);
assert_eq!(signed64(-base - half).to_bits(), (1u64 << 63) | bits);
assert_eq!(signed64(-base - half - 1).to_bits(), (1u64 << 63) | (bits + 1));
assert_eq!(signed64(i128::MIN).to_bits(), (1u64 << 63) | (1150u64 << 52));
assert_eq!(signed64(i128::MAX).to_bits(), 1150u64 << 52);
}
#[test]
fn unsigned_single_precision_rounding() {
let base = 1u128 << 64;
let half = 1u128 << 40;
let bits = 191u32 << 23;
assert_eq!(unsigned32(base + half - 1).to_bits(), bits);
assert_eq!(unsigned32(base + half).to_bits(), bits);
assert_eq!(unsigned32(base + half + 1).to_bits(), bits + 1);
assert_eq!(unsigned32(u128::MAX), f32::INFINITY);
}
#[test]
fn signed_single_precision_rounding() {
let base = 1i128 << 64;
let half = 1i128 << 40;
let bits = 191u32 << 23;
assert_eq!(signed32(base + half + 1).to_bits(), bits + 1);
assert_eq!(signed32(-base - half).to_bits(), (1u32 << 31) | bits);
assert_eq!(signed32(-base - half - 1).to_bits(), (1u32 << 31) | (bits + 1));
assert_eq!(signed32(i128::MIN).to_bits(), (1u32 << 31) | (254u32 << 23));
assert_eq!(signed32(i128::MAX).to_bits(), 254u32 << 23);
}