Skip to content

Commit

Permalink
[ci skip] FIXME
Browse files Browse the repository at this point in the history
  • Loading branch information
iliekturtles committed Jun 19, 2021
1 parent a7a4ccf commit 7d9d06d
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 64 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ typenum = "1.13"

[dev-dependencies]
approx = "0.5"
quickcheck = "0.9.2"
quickcheck = "1.0"
serde_json = "1.0"
static_assertions = "1.1"

Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,11 +441,13 @@ pub trait Conversion<V> {
/// * `V`: Underlying storage type trait is implemented for.
///
/// [factor]: https://jcgm.bipm.org/vim/en/1.24.html
#[allow(unused_qualifications)] // lib:cmp::PartialOrder false positive.
pub trait ConversionFactor<V>:
lib::ops::Add<Self, Output = Self>
+ lib::ops::Sub<Self, Output = Self>
+ lib::ops::Mul<Self, Output = Self>
+ lib::ops::Div<Self, Output = Self>
+ lib::cmp::PartialOrd
+ crate::num::Zero
+ crate::num::One
{
Expand Down
16 changes: 6 additions & 10 deletions src/si/ratio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,33 +161,29 @@ mod tests {
use crate::si::quantities::*;
use crate::tests::Test;

fn test_nan_or_eq(yl: V, yr: V) -> bool {
(yl.is_nan() && yr.is_nan()) || Test::eq(&yl, &yr)
}

quickcheck! {
fn acos(x: V) -> bool {
test_nan_or_eq(x.acos(), Ratio::from(x).acos().get::<a::radian>())
Test::eq(&x.acos(), &Ratio::from(x).acos().get::<a::radian>())
}

fn acosh(x: V) -> bool {
test_nan_or_eq(x.acosh(), Ratio::from(x).acosh().get::<a::radian>())
Test::eq(&x.acosh(), &Ratio::from(x).acosh().get::<a::radian>())
}

fn asin(x: V) -> bool {
test_nan_or_eq(x.asin(), Ratio::from(x).asin().get::<a::radian>())
Test::eq(&x.asin(), &Ratio::from(x).asin().get::<a::radian>())
}

fn asinh(x: V) -> bool {
test_nan_or_eq(x.asinh(), Ratio::from(x).asinh().get::<a::radian>())
Test::eq(&x.asinh(), &Ratio::from(x).asinh().get::<a::radian>())
}

fn atan(x: V) -> bool {
test_nan_or_eq(x.atan(), Ratio::from(x).atan().get::<a::radian>())
Test::eq(&x.atan(), &Ratio::from(x).atan().get::<a::radian>())
}

fn atanh(x: V) -> bool {
test_nan_or_eq(x.atanh(), Ratio::from(x).atanh().get::<a::radian>())
Test::eq(&x.atanh(), &Ratio::from(x).atanh().get::<a::radian>())
}
}
}
Expand Down
51 changes: 34 additions & 17 deletions src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,16 +303,24 @@ macro_rules! system {
where
D: Dimension + ?Sized,
U: Units<V> + ?Sized,
V: $crate::Conversion<V> + $crate::lib::ops::Mul<V, Output = V>,
V: $crate::Conversion<V>,
N: $crate::Conversion<V, T = V::T>,
{
use $crate::typenum::Integer;
use $crate::Conversion;
use $crate::ConversionFactor;
use $crate::{Conversion, ConversionFactor};

let v = v.into_conversion();
let n_coef = N::coefficient();
let f = V::coefficient() $(* U::$name::coefficient().powi(D::$symbol::to_i32()))+;
let n_cons = N::constant($crate::ConstantOp::Sub);

(v.into_conversion() $(* U::$name::coefficient().powi(D::$symbol::to_i32()))+
/ N::coefficient() - N::constant($crate::ConstantOp::Sub))
.value()
if n_coef < f {
(v * (f / n_coef) - n_cons).value()
}
else {
// (v * f / n_coef - n_cons).value()
(v / (n_coef / f) - n_cons).value()
}
}

/// Convert a value from the given unit to base units.
Expand All @@ -327,16 +335,24 @@ macro_rules! system {
where
D: Dimension + ?Sized,
U: Units<V> + ?Sized,
V: $crate::Conversion<V> + $crate::lib::ops::Mul<V, Output = V>,
V: $crate::Conversion<V>,
N: $crate::Conversion<V, T = V::T>,
{
use $crate::typenum::Integer;
use $crate::Conversion;
use $crate::ConversionFactor;
use $crate::{Conversion, ConversionFactor};

((v.into_conversion() + N::constant($crate::ConstantOp::Add)) * N::coefficient()
/ (V::coefficient() $(* U::$name::coefficient().powi(D::$symbol::to_i32()))+))
.value()
let v = v.into_conversion();
let n_coef = N::coefficient();
let f = V::coefficient() $(* U::$name::coefficient().powi(D::$symbol::to_i32()))+;
let n_cons = N::constant($crate::ConstantOp::Add);

if n_coef >= f {
((v + n_cons) * (n_coef / f)).value()
}
else {
(((v + n_cons) * n_coef) / f).value()
// ((v + n_cons) / (f / n_coef)).value()
}
}

autoconvert_test! {
Expand All @@ -357,12 +373,13 @@ macro_rules! system {
V: $crate::Conversion<V> + $crate::lib::ops::Mul<V, Output = V>,
{
use $crate::typenum::Integer;
use $crate::Conversion;
use $crate::ConversionFactor;
use $crate::{Conversion, ConversionFactor};

let v = v.into_conversion();
let f = V::coefficient() $(* Ur::$name::coefficient().powi(D::$symbol::to_i32())
/ Ul::$name::coefficient().powi(D::$symbol::to_i32()))+;

(v.into_conversion() $(* Ur::$name::coefficient().powi(D::$symbol::to_i32())
/ Ul::$name::coefficient().powi(D::$symbol::to_i32()))+)
.value()
(v * f).value()
}}

#[doc(hidden)]
Expand Down
44 changes: 31 additions & 13 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,37 @@ mod test_trait {
const ULPS: u32 = 3;

impl super::super::Test for V {
/// Assert that `lhs` and `rhs` are exactly equal.
fn assert_eq(lhs: &Self, rhs: &Self) {
match (lhs.is_nan(), rhs.is_nan()) {
(true, true) => {}
_ => { assert_eq!(lhs, rhs); }
}
}

/// Assert that `lhs` and `rhs` are approximately equal for floating point types or
/// exactly equal for other types.
fn assert_approx_eq(lhs: &Self, rhs: &Self) {
assert_ulps_eq!(lhs, rhs, epsilon = EPS_FACTOR * V::epsilon(), max_ulps = ULPS);
match (lhs.is_nan(), rhs.is_nan()) {
(true, true) => {}
_ => {
assert_ulps_eq!(lhs, rhs, epsilon = EPS_FACTOR * V::epsilon(),
max_ulps = ULPS);
}
}
}

/// Exactly compare `lhs` and `rhs` and return the result.
fn eq(lhs: &Self, rhs: &Self) -> bool {
(lhs.is_nan() && rhs.is_nan())
|| lhs == rhs
}

/// Approximately compare `lhs` and `rhs` for floating point types or exactly compare
/// for other types and return the result.
fn approx_eq(lhs: &Self, rhs: &Self) -> bool {
ulps_eq!(lhs, rhs, epsilon = EPS_FACTOR * V::epsilon(), max_ulps = ULPS)
(lhs.is_nan() && rhs.is_nan())
|| ulps_eq!(lhs, rhs, epsilon = EPS_FACTOR * V::epsilon(), max_ulps = ULPS)
}
}
}
Expand All @@ -140,32 +165,25 @@ impl<V> crate::lib::ops::Deref for A<V> {

mod a_struct {
storage_types! {
// Quickcheck 0.8 required for i128/u128 support. Use PrimInt after upgrade.
types: Float, usize, u8, u16, u32, u64, isize, i8, i16, i32, i64;
types: Float, PrimInt;

use super::super::A;

impl quickcheck::Arbitrary for A<V> {
fn arbitrary<G>(g: &mut G) -> Self
where
G: quickcheck::Gen,
{
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
A { v: V::arbitrary(g), }
}
}
}

storage_types! {
types: BigInt, BigUint, Ratio, i128, u128;
types: BigInt, BigUint, Ratio;

use crate::num::FromPrimitive;
use super::super::A;

impl quickcheck::Arbitrary for A<V> {
fn arbitrary<G>(g: &mut G) -> Self
where
G: quickcheck::Gen,
{
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
A {
v: loop {
let v = V::from_f64(<f64 as quickcheck::Arbitrary>::arbitrary(g));
Expand Down
Loading

0 comments on commit 7d9d06d

Please sign in to comment.