Skip to content

Commit

Permalink
[transcendental] sqrt: change error type from () to &'static str. (#7)
Browse files Browse the repository at this point in the history
* Closes #6: Resolve this by printing an error if an overflow occurs in `sqrt`due to small numbers.
* Add test that shows the approximate lower bound of working values for I32F32
* version bump: v0.5.5
  • Loading branch information
clangenb authored Jan 22, 2021
1 parent 2c52170 commit 310e0d3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

[package]
name = "substrate-fixed"
version = "0.5.4"
version = "0.5.5"
authors = ["Trevor Spiteri <tspiteri@ieee.org>"]
description = "Fixed-point numbers"
documentation = "https://docs.rs/fixed"
Expand Down
27 changes: 21 additions & 6 deletions src/transcendental.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This module contains transcendental functions.
*/
use crate::consts;
use crate::traits::{Fixed, FixedSigned, LossyFrom, ToFixed};
use crate::types::{I9F23, I9F55, U0F128, U64F64};
use crate::types::{I9F23, I9F55, U0F128};
use core::ops::{AddAssign, BitOrAssign, ShlAssign};

type ConstType = I9F23;
Expand Down Expand Up @@ -129,14 +129,14 @@ where
}

/// square root
pub fn sqrt<S, D>(operand: S) -> Result<D, ()>
pub fn sqrt<S, D>(operand: S) -> Result<D, &'static str>
where
S: Fixed + PartialOrd<ConstType>,
D: Fixed + PartialOrd<ConstType> + From<S>,
{
let mut invert = false;
if operand < ZERO {
return Err(());
return Err("Can't calculate sqrt from negative numbers.");
};

let mut operand = D::from(operand);
Expand All @@ -148,7 +148,7 @@ where
operand = if let Some(r) = D::from_num(1).checked_div(operand) {
r
} else {
return Err(());
return Err("Overflow inverting operand.");
};
}
// Newton iterations
Expand All @@ -160,7 +160,7 @@ where
l = if let Some(r) = D::from_num(1).checked_div(l) {
r
} else {
return Err(());
return Err("Overflow un-inverting operand.");
};
}
Ok(l)
Expand Down Expand Up @@ -448,7 +448,7 @@ pub fn asin<T>(angle: T) -> T {
mod tests {
use super::*;
use crate::traits::LossyInto;
use crate::types::{I32F32, I64F64};
use crate::types::{I32F32, I64F64, U64F64};

#[test]
fn sqrt_works() {
Expand All @@ -475,6 +475,21 @@ mod tests {
}
}

#[test]
fn sqrt_check_lower_bound_of_working_values() {
// Todo: This could be done for other types too.
type S = I32F32;
type D = I32F32;

// this works
let result: f64 = sqrt::<S, D>(S::from_num(5.8208e-10)).unwrap().lossy_into();
assert_relative_eq!(result, 0.0000261, epsilon = 1.0e-6);

// slightly below lower bound that produces an overflow
let res = sqrt::<S, D>(S::from_num(5.8205e-10));
assert_eq!(res.unwrap_err(), "Overflow inverting operand.")
}

#[test]
fn rs_works() {
let result: f64 = rs(I9F23::from_num(0)).lossy_into();
Expand Down

0 comments on commit 310e0d3

Please sign in to comment.