@@ -55,25 +55,26 @@ HWY_API V SinCos(Prec &prec, V x) {
5555 constexpr bool kIsSingle = std::is_same_v<TFromV<V>, float >;
5656 const DFromV<V> d;
5757 V ret;
58-
5958 // Step 1: Select base algorithm based on accuracy requirements
6059 if constexpr (Prec::kLowAccuracy ) {
6160 // Low precision: Cody-Waite reduction with degree-9 polynomial
62- // Error: ~1- 2 ULP
61+ // Error: ~2 ULP and 3~ for non-fma
6362 ret = Low<IS_COS>(x);
6463 } else {
6564 // High precision: π/16 reduction with table lookup + polynomial
66- // Error: ~0.5 ULP
65+ // Error: ~1 ULP
6766 ret = High<IS_COS>(x);
6867 }
69-
7068 // Step 2: Handle special cases (NaN, Inf) if enabled
7169 auto is_finite = IsFinite (x);
7270 if constexpr (Prec::kSpecialCases ) {
7371 // IEEE 754 requires: sin(±∞) = NaN, cos(±∞) = NaN
7472 ret = IfThenElse (is_finite, ret, NaN (d));
73+ // -0.0 should return -0.0 for sine
74+ if constexpr (!IS_COS) {
75+ ret = IfThenElse (Eq (x, Set (d, 0.0 )), x, ret);
76+ }
7577 }
76-
7778 // Step 3: Handle very large arguments if enabled
7879 // For |x| > threshold, standard algorithms lose precision due to
7980 // catastrophic cancellation in x - n*π reduction
@@ -91,12 +92,10 @@ HWY_API V SinCos(Prec &prec, V x) {
9192 ret = IfThenElse (has_large_arg, Extended<IS_COS>(x), ret);
9293 }
9394 }
94-
9595 // Step 4: Raise invalid operation exception for infinity inputs
9696 if constexpr (Prec::kExceptions ) {
9797 prec.Raise (!AllFalse (d, IsInf (x)) ? FPExceptions::kInvalid : 0 );
9898 }
99-
10099 return ret;
101100}
102101
0 commit comments