+ fn reference_sin_cos_pi_f64(mut v: f64) -> (f64, f64) {
+ use az::Cast;
+ use rug::{float::Constant, Float};
+ if !v.is_finite() {
+ return (f64::NAN, f64::NAN);
+ }
+ v %= 2.0;
+ if v >= 1.0 {
+ v -= 2.0;
+ } else if v <= -1.0 {
+ v += 2.0;
+ }
+ v *= 2.0;
+ let part = v.round() as i32;
+ v -= part as f64;
+ let precision = 100;
+ let mut v = Float::with_val(precision, v);
+ let pi = Float::with_val(precision, Constant::Pi);
+ let pi_2 = pi / 2;
+ v *= &pi_2;
+ let cos = pi_2; // just a temp var, value is ignored
+ let (sin, cos) = v.sin_cos(cos);
+ let sin: f64 = sin.cast();
+ let cos: f64 = cos.cast();
+ match part {
+ 0 => (sin, cos),
+ 1 => (cos, -sin),
+ 2 => (-sin, -cos),
+ -2 => (-sin, -cos),
+ -1 => (-cos, sin),
+ _ => panic!("not implemented: part={}", part),
+ }
+ }
+
+ macro_rules! test_reference_sin_cos_pi_test_cases {
+ ($case:expr, $ty:ident) => {
+ $case($ty::NAN, $ty::NAN, $ty::NAN);
+ $case($ty::INFINITY, $ty::NAN, $ty::NAN);
+ $case(-$ty::INFINITY, $ty::NAN, $ty::NAN);
+ $case(-4., 0., 1.);
+ $case(
+ -3.875,
+ 0.38268343236508977172845998403039886676134456248563,
+ 0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(
+ -3.75,
+ 0.70710678118654752440084436210484903928483593768847,
+ 0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ -3.625,
+ 0.92387953251128675612818318939678828682241662586364,
+ 0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(-3.5, 1., -0.);
+ $case(
+ -3.375,
+ 0.92387953251128675612818318939678828682241662586364,
+ -0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(
+ -3.25,
+ 0.70710678118654752440084436210484903928483593768847,
+ -0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ -3.125,
+ 0.38268343236508977172845998403039886676134456248563,
+ -0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(-3., -0., -1.);
+ $case(
+ -2.875,
+ -0.38268343236508977172845998403039886676134456248563,
+ -0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(
+ -2.75,
+ -0.70710678118654752440084436210484903928483593768847,
+ -0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ -2.625,
+ -0.92387953251128675612818318939678828682241662586364,
+ -0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(-2.5, -1., 0.);
+ $case(
+ -2.375,
+ -0.92387953251128675612818318939678828682241662586364,
+ 0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(
+ -2.25,
+ -0.70710678118654752440084436210484903928483593768847,
+ 0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ -2.125,
+ -0.38268343236508977172845998403039886676134456248563,
+ 0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(-2., 0., 1.);
+ $case(
+ -1.875,
+ 0.38268343236508977172845998403039886676134456248563,
+ 0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(
+ -1.75,
+ 0.70710678118654752440084436210484903928483593768847,
+ 0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ -1.625,
+ 0.92387953251128675612818318939678828682241662586364,
+ 0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(-1.5, 1., -0.);
+ $case(
+ -1.375,
+ 0.92387953251128675612818318939678828682241662586364,
+ -0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(
+ -1.25,
+ 0.70710678118654752440084436210484903928483593768847,
+ -0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ -1.125,
+ 0.38268343236508977172845998403039886676134456248563,
+ -0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(-1., -0., -1.);
+ $case(
+ -0.875,
+ -0.38268343236508977172845998403039886676134456248563,
+ -0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(
+ -0.75,
+ -0.70710678118654752440084436210484903928483593768847,
+ -0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ -0.625,
+ -0.92387953251128675612818318939678828682241662586364,
+ -0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(-0.5, -1., 0.);
+ $case(
+ -0.375,
+ -0.92387953251128675612818318939678828682241662586364,
+ 0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(
+ -0.25,
+ -0.70710678118654752440084436210484903928483593768847,
+ 0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ -0.125,
+ -0.38268343236508977172845998403039886676134456248563,
+ 0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(0., 0., 1.);
+ $case(
+ 0.125,
+ 0.38268343236508977172845998403039886676134456248563,
+ 0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(
+ 0.25,
+ 0.70710678118654752440084436210484903928483593768847,
+ 0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ 0.375,
+ 0.92387953251128675612818318939678828682241662586364,
+ 0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(0.5, 1., 0.);
+ $case(
+ 0.625,
+ 0.92387953251128675612818318939678828682241662586364,
+ -0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(
+ 0.75,
+ 0.70710678118654752440084436210484903928483593768847,
+ -0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ 0.875,
+ 0.38268343236508977172845998403039886676134456248563,
+ -0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(1., 0., -1.);
+ $case(
+ 1.125,
+ -0.38268343236508977172845998403039886676134456248563,
+ -0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(
+ 1.25,
+ -0.70710678118654752440084436210484903928483593768847,
+ -0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ 1.375,
+ -0.92387953251128675612818318939678828682241662586364,
+ -0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(1.5, -1., -0.);
+ $case(
+ 1.625,
+ -0.92387953251128675612818318939678828682241662586364,
+ 0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(
+ 1.75,
+ -0.70710678118654752440084436210484903928483593768847,
+ 0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ 1.875,
+ -0.38268343236508977172845998403039886676134456248563,
+ 0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(2., -0., 1.);
+ $case(
+ 2.125,
+ 0.38268343236508977172845998403039886676134456248563,
+ 0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(
+ 2.25,
+ 0.70710678118654752440084436210484903928483593768847,
+ 0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ 2.375,
+ 0.92387953251128675612818318939678828682241662586364,
+ 0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(2.5, 1., 0.);
+ $case(
+ 2.625,
+ 0.92387953251128675612818318939678828682241662586364,
+ -0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(
+ 2.75,
+ 0.70710678118654752440084436210484903928483593768847,
+ -0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ 2.875,
+ 0.38268343236508977172845998403039886676134456248563,
+ -0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(3., 0., -1.);
+ $case(
+ 3.125,
+ -0.38268343236508977172845998403039886676134456248563,
+ -0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(
+ 3.25,
+ -0.70710678118654752440084436210484903928483593768847,
+ -0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ 3.375,
+ -0.92387953251128675612818318939678828682241662586364,
+ -0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(3.5, -1., -0.);
+ $case(
+ 3.625,
+ -0.92387953251128675612818318939678828682241662586364,
+ 0.38268343236508977172845998403039886676134456248563,
+ );
+ $case(
+ 3.75,
+ -0.70710678118654752440084436210484903928483593768847,
+ 0.70710678118654752440084436210484903928483593768847,
+ );
+ $case(
+ 3.875,
+ -0.38268343236508977172845998403039886676134456248563,
+ 0.92387953251128675612818318939678828682241662586364,
+ );
+ $case(4., -0., 1.);
+ };
+ }
+