Skip to content

Commit

Permalink
fix overflow test when casting f64,f32 -> u64 & f32 -> u32
Browse files Browse the repository at this point in the history
closes #15
  • Loading branch information
japaric committed Nov 16, 2019
1 parent 856b833 commit 3f0bf8b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 13 deletions.
34 changes: 21 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,7 @@
#![deny(missing_docs)]
#![deny(warnings)]
#![allow(const_err)]

#![cfg_attr(not(feature = "std"), no_std)]

#![cfg_attr(feature = "x128", feature(i128_type, i128))]

#[cfg(feature = "std")]
Expand All @@ -106,7 +104,7 @@ extern crate core;
extern crate quickcheck;

use core::fmt;
#[cfg(feature="std")]
#[cfg(feature = "std")]
use std::error;

#[cfg(test)]
Expand Down Expand Up @@ -146,7 +144,7 @@ impl fmt::Display for Error {
}
}

#[cfg(feature="std")]
#[cfg(feature = "std")]
impl error::Error for Error {
fn description(&self) -> &str {
self.description_helper()
Expand Down Expand Up @@ -273,7 +271,7 @@ macro_rules! from_signed {

/// From a float `$src` to an integer `$dst`
macro_rules! from_float {
($($src:ident => $($dst:ident),+);+;) => {
($($src:ident, $usrc:ident => $($dst:ident),+);+;) => {
$(
$(
impl From<$src> for $dst {
Expand All @@ -288,7 +286,16 @@ macro_rules! from_float {
} else if src == $src::INFINITY ||
src == $src::NEG_INFINITY {
Error::Infinite
} else if src > $dst::MAX as $src {
} else if {
// we subtract 1 ULP (unit of least precision) here because some
// lossy conversions like `u64::MAX as f64` round *up* and we want
// to avoid this evaluating to false in that case
use core::mem::transmute;
let max = unsafe {
transmute::<_, $src>(transmute::<_, $usrc>($dst::MAX as $src) - 1)
};
src > max
} {
Error::Overflow
} else if $dst::MIN == 0 {
// when casting to unsigned integer, negative values close to 0 but
Expand Down Expand Up @@ -398,8 +405,8 @@ mod _32 {
}

from_float! {
f32 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
f64 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
f32, u32 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
f64, f32 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
}
}

Expand Down Expand Up @@ -456,8 +463,8 @@ mod _64 {
}

from_float! {
f32 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
f64 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
f32, u32 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
f64, u64 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
}
}

Expand Down Expand Up @@ -504,11 +511,12 @@ mod _x128 {

// Float
from_float! {
f32 => i128;
f64 => i128, u128;
f32, u32 => i128;
f64, u64 => i128, u128;
}

from_float_dst! {
f32 => u128;
f32 => u128;
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,18 @@ fn gh16() {
assert_eq!(super::u32(0.99_f64), Ok(0));
assert_eq!(super::u32(0.01_f32), Ok(0));
}

#[test]
fn gh15() {
assert_eq!(super::u32(32_f32.exp2()), Err(super::Error::Overflow));
assert_eq!(super::u32(32_f64.exp2()), Err(super::Error::Overflow));

assert_eq!(super::u64(64_f32.exp2()), Err(super::Error::Overflow));
assert_eq!(super::u64(64_f64.exp2()), Err(super::Error::Overflow));

assert_eq!(super::u8(8_f32.exp2()), Err(super::Error::Overflow));
assert_eq!(super::u8(8_f64.exp2()), Err(super::Error::Overflow));

assert_eq!(super::u16(16_f32.exp2()), Err(super::Error::Overflow));
assert_eq!(super::u16(16_f64.exp2()), Err(super::Error::Overflow));
}

0 comments on commit 3f0bf8b

Please sign in to comment.