pub fn sum_relative_error_bound(num_values: i32) -> f64 {
if num_values <= 1 {
return 0.0;
}
let u = f64::from_bits(((1023 - 52) as u64) << 52); (num_values - 1) as f64 * u
}
pub fn sum_upper_bound(sum: f64, num_values: i32) -> f64 {
if num_values <= 2 {
return sum;
}
let b = sum_relative_error_bound(num_values);
(1.0 + 2.0 * b) * sum
}
pub fn unsigned_min(a: i32, b: i32) -> i32 {
if (a as u32) < (b as u32) { a } else { b }
}
#[cfg(test)]
mod tests {
use super::*;
use assertables::*;
#[test]
fn test_sum_relative_error_bound_zero_values() {
assert_eq!(sum_relative_error_bound(0), 0.0);
}
#[test]
fn test_sum_relative_error_bound_one_value() {
assert_eq!(sum_relative_error_bound(1), 0.0);
}
#[test]
fn test_sum_relative_error_bound_two_values() {
let bound = sum_relative_error_bound(2);
assert_gt!(bound, 0.0);
assert_in_delta!(bound, 2.220446049250313e-16, 1e-30);
}
#[test]
fn test_sum_relative_error_bound_ten_values() {
let bound = sum_relative_error_bound(10);
assert_in_delta!(bound, 9.0 * 2.220446049250313e-16, 1e-29);
}
#[test]
fn test_sum_upper_bound_two_values() {
assert_eq!(sum_upper_bound(10.0, 2), 10.0);
}
#[test]
fn test_sum_upper_bound_one_value() {
assert_eq!(sum_upper_bound(5.0, 1), 5.0);
}
#[test]
fn test_sum_upper_bound_three_values() {
let result = sum_upper_bound(10.0, 3);
assert_gt!(result, 10.0);
assert_in_delta!(result, 10.0, 1e-13);
}
#[test]
fn test_unsigned_min_both_positive() {
assert_eq!(unsigned_min(3, 5), 3);
assert_eq!(unsigned_min(5, 3), 3);
}
#[test]
fn test_unsigned_min_negative_is_larger() {
assert_eq!(unsigned_min(-1, 5), 5);
assert_eq!(unsigned_min(5, -1), 5);
}
#[test]
fn test_unsigned_min_both_negative() {
assert_eq!(unsigned_min(-1, -2), -2);
}
}