Skip to content

Commit

Permalink
Fixed exponent bug
Browse files Browse the repository at this point in the history
  • Loading branch information
elichai committed Aug 26, 2019
1 parent a080458 commit 6882d73
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ before_script:
cd "${TRAVIS_BUILD_DIR}/random-trait"
rustup component add clippy-preview rustfmt;
cargo fmt --all -- --check;
cargo clippy --all-targets --all-features -- -D clippy::all;
cargo clippy --all-targets --all-features -- -Dwarnings -Aclippy::transmute_int_to_float -Aclippy::new-without-default;

cd "${TRAVIS_BUILD_DIR}/random-fast-rng"
rustup component add clippy-preview rustfmt;
cargo fmt --all -- --check;
cargo clippy --all-targets --all-features -- -D warnings -A clippy::new-without-default;
cargo clippy --all-targets --all-features -- -Dwarnings -Aclippy::transmute_int_to_float -Aclippy::new-without-default;
fi
- if [ ${TRAVIS_RUST_VERSION} == "nightly" ]; then
cd "${TRAVIS_BUILD_DIR}/random-trait"
Expand Down
23 changes: 18 additions & 5 deletions random-trait/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ impl GenerateRand for f64 {
while significand == 0 {
exponent -= 64;
if exponent < -1074i32 {
// emin(-1022)-p(53)+1 (https://en.wikipedia.org/wiki/IEEE_754)
// E min(-1022)-p(53)+1 (https://en.wikipedia.org/wiki/IEEE_754)
// In reallity this should probably never happen. prob of ~1/(2^1024) unless randomness is broken.
unreachable!("The randomness is broken, got 0 16 times. (prob of 1/2^1024)");
}
Expand All @@ -252,7 +252,7 @@ impl GenerateRand for f64 {
significand |= 1;

// Convert to float and scale by 2^exponent.
significand as f64 * (1.0 / 2u64.pow(exponent.abs() as u32) as f64)
significand as f64 * exp2(exponent)
}
}

Expand All @@ -265,7 +265,7 @@ impl GenerateRand for f32 {
while significand == 0 {
exponent -= 32;
if exponent < -149i32 {
// emin(-126)-p(24)+1 (https://en.wikipedia.org/wiki/IEEE_754)
// E min(-126)-p(24)+1 (https://en.wikipedia.org/wiki/IEEE_754)
// In reallity this should probably never happen. prob of ~1/(2^1024) unless randomness is broken.
unreachable!("The randomness is broken, got 0 5 times. (prob of 1/2^160)");
// TODO: Should this stay unreachable or change to return 0?
Expand All @@ -275,7 +275,7 @@ impl GenerateRand for f32 {

// Shift the leading zeros into the exponent
let shift = significand.leading_zeros() as i32;
if shift > 0 {
if shift != 0 {
exponent -= shift;
significand <<= shift;
significand |= rand.get_u32() >> (32 - shift);
Expand All @@ -284,10 +284,23 @@ impl GenerateRand for f32 {
significand |= 1;

// Convert to float and scale by 2^exponent.
significand as f32 * (1.0 / 2u32.pow(exponent.abs() as u32) as f32)
significand as f32 * exp2f(exponent)
}
}

/// This is from IEEE-754.
/// you take the E max, subtract the exponent from it, and shift it according to the precision-1
fn exp2f(exp: i32) -> f32 {
debug_assert!(exp > -127);
let bits = ((127i32 + exp) as u32) << 23u32;
unsafe { mem::transmute(bits) } // this is the same as `f32::from_bits`
}
fn exp2(exp: i32) -> f64 {
debug_assert!(exp > -1023);
let bits = ((1023i32 + exp) as u64) << 52u64;
unsafe { mem::transmute(bits) } // this is the same as `f64::from_bits`
}

// Will overflow(i.e. sign extend) correctly https://doc.rust-lang.org/nomicon/casts.html.
// should only be used with the same type.
macro_rules! impl_generate_rand_ifromu {
Expand Down

0 comments on commit 6882d73

Please sign in to comment.