forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Restore `rintf*` intrinsics * Remove negative tests * Restore `nearbyintf*` intrinsics * Remove negative tests * Add tests for `rintf*` and `nearbyintf*` * Require `diff` to be [0, 0.5]
- Loading branch information
1 parent
887c2e3
commit 252c1ce
Showing
11 changed files
with
412 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
tests/kani/Intrinsics/Math/Rounding/NearbyInt/nearbyintf32.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
||
// Checks that `nearbyintf32` returns the nearest integer to the argument. The | ||
// default rounding mode is rounding half to even, which is described here: | ||
// https://en.wikipedia.org/wiki/Rounding#Round_half_to_even | ||
#![feature(core_intrinsics)] | ||
use std::intrinsics::nearbyintf32; | ||
|
||
#[kani::proof] | ||
fn test_one() { | ||
let one = 1.0; | ||
let result = unsafe { nearbyintf32(one) }; | ||
assert!(result == 1.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_one_frac() { | ||
let one_frac = 1.9; | ||
let result = unsafe { nearbyintf32(one_frac) }; | ||
assert!(result == 2.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_half_down() { | ||
let one_frac = 2.5; | ||
let result = unsafe { nearbyintf32(one_frac) }; | ||
assert!(result == 2.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_half_up() { | ||
let one_frac = 3.5; | ||
let result = unsafe { nearbyintf32(one_frac) }; | ||
assert!(result == 4.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_conc() { | ||
let conc = -42.6; | ||
let result = unsafe { nearbyintf32(conc) }; | ||
assert!(result == -43.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_conc_sci() { | ||
let conc = 5.4e-2; | ||
let result = unsafe { nearbyintf32(conc) }; | ||
assert!(result == 0.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_towards_nearest() { | ||
let x: f32 = kani::any(); | ||
kani::assume(!x.is_nan()); | ||
kani::assume(!x.is_infinite()); | ||
let result = unsafe { nearbyintf32(x) }; | ||
let frac = x.fract().abs(); | ||
if x.is_sign_positive() { | ||
if frac > 0.5 { | ||
assert!(result > x); | ||
} else if frac < 0.5 { | ||
assert!(result <= x); | ||
} else { | ||
// This would fail if conversion checks were on | ||
let integer = x as i64; | ||
if integer % 2 == 0 { | ||
assert!(result < x); | ||
} else { | ||
assert!(result > x); | ||
} | ||
} | ||
} else { | ||
if frac > 0.5 { | ||
assert!(result < x); | ||
} else if frac < 0.5 { | ||
assert!(result >= x); | ||
} else { | ||
// This would fail if conversion checks were on | ||
let integer = x as i64; | ||
if integer % 2 == 0 { | ||
assert!(result > x); | ||
} else { | ||
assert!(result < x); | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[kani::proof] | ||
fn test_diff_half_one() { | ||
let x: f32 = kani::any(); | ||
kani::assume(!x.is_nan()); | ||
kani::assume(!x.is_infinite()); | ||
let result = unsafe { nearbyintf32(x) }; | ||
let diff = (x - result).abs(); | ||
assert!(diff <= 0.5); | ||
assert!(diff >= 0.0); | ||
} |
99 changes: 99 additions & 0 deletions
99
tests/kani/Intrinsics/Math/Rounding/NearbyInt/nearbyintf64.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
||
// Checks that `nearbyintf64` returns the nearest integer to the argument. The | ||
// default rounding mode is rounding half to even, which is described here: | ||
// https://en.wikipedia.org/wiki/Rounding#Round_half_to_even | ||
#![feature(core_intrinsics)] | ||
use std::intrinsics::nearbyintf64; | ||
|
||
#[kani::proof] | ||
fn test_one() { | ||
let one = 1.0; | ||
let result = unsafe { nearbyintf64(one) }; | ||
assert!(result == 1.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_one_frac() { | ||
let one_frac = 1.9; | ||
let result = unsafe { nearbyintf64(one_frac) }; | ||
assert!(result == 2.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_half_down() { | ||
let one_frac = 2.5; | ||
let result = unsafe { nearbyintf64(one_frac) }; | ||
assert!(result == 2.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_half_up() { | ||
let one_frac = 3.5; | ||
let result = unsafe { nearbyintf64(one_frac) }; | ||
assert!(result == 4.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_conc() { | ||
let conc = -42.6; | ||
let result = unsafe { nearbyintf64(conc) }; | ||
assert!(result == -43.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_conc_sci() { | ||
let conc = 5.4e-2; | ||
let result = unsafe { nearbyintf64(conc) }; | ||
assert!(result == 0.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_towards_nearest() { | ||
let x: f64 = kani::any(); | ||
kani::assume(!x.is_nan()); | ||
kani::assume(!x.is_infinite()); | ||
let result = unsafe { nearbyintf64(x) }; | ||
let frac = x.fract().abs(); | ||
if x.is_sign_positive() { | ||
if frac > 0.5 { | ||
assert!(result > x); | ||
} else if frac < 0.5 { | ||
assert!(result <= x); | ||
} else { | ||
// This would fail if conversion checks were on | ||
let integer = x as i64; | ||
if integer % 2 == 0 { | ||
assert!(result < x); | ||
} else { | ||
assert!(result > x); | ||
} | ||
} | ||
} else { | ||
if frac > 0.5 { | ||
assert!(result < x); | ||
} else if frac < 0.5 { | ||
assert!(result >= x); | ||
} else { | ||
// This would fail if conversion checks were on | ||
let integer = x as i64; | ||
if integer % 2 == 0 { | ||
assert!(result > x); | ||
} else { | ||
assert!(result < x); | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[kani::proof] | ||
fn test_diff_half_one() { | ||
let x: f64 = kani::any(); | ||
kani::assume(!x.is_nan()); | ||
kani::assume(!x.is_infinite()); | ||
let result = unsafe { nearbyintf64(x) }; | ||
let diff = (x - result).abs(); | ||
assert!(diff <= 0.5); | ||
assert!(diff >= 0.0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
||
// Checks that `rintf32` returns the nearest integer to the argument. The | ||
// default rounding mode is rounding half to even, which is described here: | ||
// https://en.wikipedia.org/wiki/Rounding#Round_half_to_even | ||
// | ||
// `rintf32` works like `nearbyintf32`, but it may raise an inexact | ||
// floating-point exception which isn't supported in Rust: | ||
// https://github.com/rust-lang/rust/issues/10186 | ||
// So in practice, `rintf32` and `nearbyintf32` work the same way. | ||
#![feature(core_intrinsics)] | ||
use std::intrinsics::rintf32; | ||
|
||
#[kani::proof] | ||
fn test_one() { | ||
let one = 1.0; | ||
let result = unsafe { rintf32(one) }; | ||
assert!(result == 1.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_one_frac() { | ||
let one_frac = 1.9; | ||
let result = unsafe { rintf32(one_frac) }; | ||
assert!(result == 2.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_half_down() { | ||
let one_frac = 2.5; | ||
let result = unsafe { rintf32(one_frac) }; | ||
assert!(result == 2.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_half_up() { | ||
let one_frac = 3.5; | ||
let result = unsafe { rintf32(one_frac) }; | ||
assert!(result == 4.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_conc() { | ||
let conc = -42.6; | ||
let result = unsafe { rintf32(conc) }; | ||
assert!(result == -43.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_conc_sci() { | ||
let conc = 5.4e-2; | ||
let result = unsafe { rintf32(conc) }; | ||
assert!(result == 0.0); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_towards_nearest() { | ||
let x: f32 = kani::any(); | ||
kani::assume(!x.is_nan()); | ||
kani::assume(!x.is_infinite()); | ||
let result = unsafe { rintf32(x) }; | ||
let frac = x.fract().abs(); | ||
if x.is_sign_positive() { | ||
if frac > 0.5 { | ||
assert!(result > x); | ||
} else if frac < 0.5 { | ||
assert!(result <= x); | ||
} else { | ||
// This would fail if conversion checks were on | ||
let integer = x as i64; | ||
if integer % 2 == 0 { | ||
assert!(result < x); | ||
} else { | ||
assert!(result > x); | ||
} | ||
} | ||
} else { | ||
if frac > 0.5 { | ||
assert!(result < x); | ||
} else if frac < 0.5 { | ||
assert!(result >= x); | ||
} else { | ||
// This would fail if conversion checks were on | ||
let integer = x as i64; | ||
if integer % 2 == 0 { | ||
assert!(result > x); | ||
} else { | ||
assert!(result < x); | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[kani::proof] | ||
fn test_diff_half_one() { | ||
let x: f32 = kani::any(); | ||
kani::assume(!x.is_nan()); | ||
kani::assume(!x.is_infinite()); | ||
let result = unsafe { rintf32(x) }; | ||
let diff = (x - result).abs(); | ||
assert!(diff <= 0.5); | ||
assert!(diff >= 0.0); | ||
} |
Oops, something went wrong.