macro_rules! test_impl {
(D, $bits: literal) => {
paste::paste! { test_impl!(SIGNED: $bits, [< dec $bits >], [<D $bits>]); }
};
(UD, $bits: literal) => {
paste::paste! { test_impl!(UNSIGNED: $bits, [< udec $bits >], [<UD $bits>]); }
};
(UNSIGNED: $bits: tt, $dec: ident, $D: ident) => {
mod $dec {
use rstest::*;
use fastnum::{*, decimal::*};
super::test_impl!(COMMON:: $bits, $dec, $D, THIS);
super::test_impl!(UNSIGNED:: $bits, $dec, $D, THIS);
}
};
(SIGNED: $bits: tt, $dec: ident, $D: ident) => {
mod $dec {
use rstest::*;
use fastnum::{*, decimal::*};
super::test_impl!(COMMON:: $bits, $dec, $D, THIS);
super::test_impl!(SIGNED:: $bits, $dec, $D, THIS);
}
};
(COMMON:: 512, $dec: ident, $D: ident, THIS) => {
super::test_impl!(COMMON:: 256, $dec, $D);
};
(UNSIGNED:: 512, $dec: ident, $D: ident, THIS) => {
super::test_impl!(UNSIGNED:: 256, $dec, $D);
};
(SIGNED:: 512, $dec: ident, $D: ident, THIS) => {
super::test_impl!(SIGNED:: 256, $dec, $D);
};
(COMMON:: 256, $dec: ident, $D: ident, THIS) => {
super::test_impl!(COMMON:: 256, $dec, $D);
#[rstest(::trace)]
#[case($dec!(1), $D::E)]
#[case($dec!(1.5), $dec!(4.4816890703380648226020554601192758190057498683696670567726500827859366744667))]
#[case($dec!(2), $dec!(7.3890560989306502272304274605750078131803155705518473240871278225225737960791))]
#[case($dec!(2.5), $dec!(12.182493960703473438070175951167966183182767790063161311560398341838185126143))]
#[case($dec!(3), $dec!(20.085536923187667740928529654581717896987907838554150144378934229698845878092))]
#[case($dec!(4), $dec!(54.598150033144239078110261202860878402790737038614068725826593958553662099936))]
#[case($dec!(5), $dec!(148.41315910257660342111558004055227962348766759387898904675284511091206482096))]
#[case($dec!(10), $dec!(22026.465794806716516957900645284244366353512618556781074235426355225202818571))]
#[case($dec!(15), $dec!(3269017.3724721106393018550460917213155057385438200342066295627732420213327489))]
#[case($dec!(100), $dec!(2.6881171418161354484126255515800135873611118773741922415191608615280287034910e+43))]
fn test_exp_256(#[case] d: $D, #[case] expected: $D) {
let res = d.exp();
assert_eq!(res, expected);
assert!(res.is_op_inexact());
assert!(res.is_op_rounded());
}
};
(COMMON:: 256, $dec: ident, $D: ident) => {
super::test_impl!(COMMON:: 128, $dec, $D);
};
(UNSIGNED:: 256, $dec: ident, $D: ident, THIS) => {
super::test_impl!(UNSIGNED:: 256, $dec, $D);
};
(UNSIGNED:: 256, $dec: ident, $D: ident) => {
super::test_impl!(UNSIGNED:: 128, $dec, $D);
};
(SIGNED:: 256, $dec: ident, $D: ident, THIS) => {
super::test_impl!(SIGNED:: 256, $dec, $D);
#[rstest(::trace)]
#[case($dec!(-1), $dec!(0.36787944117144232159552377016146086744581113103176783450783680169746149574490))]
fn test_exp_256_signed(#[case] d: $D, #[case] expected: $D) {
let res = d.exp();
assert_eq!(res, expected);
assert!(res.is_op_inexact());
assert!(res.is_op_rounded());
}
};
(SIGNED:: 256, $dec: ident, $D: ident) => {
super::test_impl!(SIGNED:: 128, $dec, $D);
};
(COMMON:: 128, $dec: ident, $D: ident, THIS) => {
super::test_impl!(COMMON:: 128, $dec, $D);
#[rstest(::trace)]
#[case($dec!(1), $D::E)]
#[case($dec!(1.5), $dec!(4.4816890703380648226020554601192758190))]
#[case($dec!(2), $dec!(7.3890560989306502272304274605750078132))]
#[case($dec!(2.5), $dec!(12.1824939607034734380701759511679661832))]
#[case($dec!(3), $dec!(20.0855369231876677409285296545817178970))]
#[case($dec!(4), $dec!(54.598150033144239078110261202860878403))]
#[case($dec!(5), $dec!(148.413159102576603421115580040552279623))]
#[case($dec!(10), $dec!(22026.4657948067165169579006452842443664))]
#[case($dec!(15), $dec!(3269017.37247211063930185504609172131551))]
#[case($dec!(100), $dec!(2.68811714181613544841262555158001358736e+43))]
fn test_exp_128(#[case] d: $D, #[case] expected: $D) {
let res = d.exp();
assert_eq!(res, expected);
assert!(res.is_op_inexact());
assert!(res.is_op_rounded());
}
};
(COMMON:: 128, $dec: ident, $D: ident) => {
#[rstest(::trace)]
#[case($dec!(0), $D::ONE)]
#[case($D::INFINITY, $D::INFINITY)]
fn test_exp_special(#[case] d: $D, #[case] expected: $D) {
let res = d.exp();
assert_eq!(res, expected);
assert_eq!(res.op_signals(), signals![]);
}
#[rstest(::trace)]
#[case($dec!(1), $D::E)]
fn test_exp(#[case] d: $D, #[case] expected: $D) {
let res = d.exp();
assert_eq!(res, expected);
assert!(res.is_op_inexact());
assert!(res.is_op_rounded());
}
#[rstest(::trace)]
#[case($D::NAN)]
fn test_exp_nan(#[case] d: $D) {
let ctx = Context::default().without_traps();
let res = d.with_ctx(ctx).exp();
assert!(res.is_nan());
assert!(res.is_op_invalid());
}
};
(UNSIGNED:: 128, $dec: ident, $D: ident, THIS) => {
super::test_impl!(UNSIGNED:: 128, $dec, $D);
};
(UNSIGNED:: 128, $dec: ident, $D: ident) => {
};
(SIGNED:: 128, $dec: ident, $D: ident, THIS) => {
super::test_impl!(SIGNED:: 128, $dec, $D);
#[rstest(::trace)]
#[case($dec!(-1), $dec!(0.36787944117144232159552377016146086745))]
fn test_exp_128_signed(#[case] d: $D, #[case] expected: $D) {
let res = d.exp();
assert_eq!(res, expected);
assert!(res.is_op_inexact());
assert!(res.is_op_rounded());
}
};
(SIGNED:: 128, $dec: ident, $D: ident) => {
#[rstest(::trace)]
#[case($dec!(-0), $D::ONE)]
#[case($D::NEG_INFINITY, $D::ZERO)]
fn test_exp_special_signed(#[case] d: $D, #[case] expected: $D) {
let res = d.exp();
assert_eq!(res, expected);
assert_eq!(res.op_signals(), signals![]);
}
};
}
pub(crate) use test_impl;