@@ -102,7 +102,7 @@ public static TVectorDouble CosDouble<TVectorDouble, TVectorInt64>(TVectorDouble
102102 result = TVectorDouble . MultiplyAddEstimate ( TVectorDouble . Create ( - 0.5 ) , x2 , TVectorDouble . One ) ;
103103 }
104104 }
105- else
105+ else if ( TVectorDouble . LessThanAll ( ax , TVectorDouble . Create ( 5000000.0 ) ) )
106106 {
107107 // at least one element is: |x| > (pi / 4) -or- infinite -or- nan
108108 ( TVectorDouble r , TVectorDouble rr , TVectorInt64 region ) = SinCosReduce < TVectorDouble , TVectorInt64 > ( ax ) ;
@@ -136,12 +136,29 @@ public static TVectorDouble CosDouble<TVectorDouble, TVectorInt64>(TVectorDouble
136136 result
137137 ) ;
138138 }
139+ else
140+ {
141+ return ScalarFallback ( x ) ;
142+ }
139143
140144 return TVectorDouble . ConditionalSelect (
141145 Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ,
142146 result , // for elements: |x| >= 2^-27, infinity, or NaN
143147 TVectorDouble . One // for elements: 2^-27 > |x|
144148 ) ;
149+
150+ static TVectorDouble ScalarFallback ( TVectorDouble x )
151+ {
152+ TVectorDouble result = TVectorDouble . Zero ;
153+
154+ for ( int i = 0 ; i < TVectorDouble . Count ; i ++ )
155+ {
156+ double scalar = double . Cos ( x [ i ] ) ;
157+ result = result . WithElement ( i , scalar ) ;
158+ }
159+
160+ return result ;
161+ }
145162 }
146163
147164 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -244,7 +261,7 @@ public static TVectorSingle CosSingle<TVectorSingle, TVectorInt32, TVectorDouble
244261 result = TVectorSingle . MultiplyAddEstimate ( TVectorSingle . Create ( - 0.5f ) , x2 , TVectorSingle . One ) ;
245262 }
246263 }
247- else
264+ else if ( TVectorSingle . LessThanAll ( ax , TVectorSingle . Create ( 5000000.0f ) ) )
248265 {
249266 // at least one element is: |x| > (pi / 4) -or- infinite -or- nan
250267
@@ -276,6 +293,10 @@ public static TVectorSingle CosSingle<TVectorSingle, TVectorInt32, TVectorDouble
276293 result
277294 ) ;
278295 }
296+ else
297+ {
298+ return ScalarFallback ( x ) ;
299+ }
279300
280301 return TVectorSingle . ConditionalSelect (
281302 Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ,
@@ -303,6 +324,19 @@ static TVectorDouble CoreImpl(TVectorDouble ax)
303324 - result // region 1 or 2
304325 ) ;
305326 }
327+
328+ static TVectorSingle ScalarFallback ( TVectorSingle x )
329+ {
330+ TVectorSingle result = TVectorSingle . Zero ;
331+
332+ for ( int i = 0 ; i < TVectorSingle . Count ; i ++ )
333+ {
334+ float scalar = float . Cos ( x [ i ] ) ;
335+ result = result . WithElement ( i , scalar ) ;
336+ }
337+
338+ return result ;
339+ }
306340 }
307341
308342 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -1733,24 +1767,22 @@ public static (TVectorDouble Sin, TVectorDouble Cos) SinCosDouble<TVectorDouble,
17331767 cosResult = TVectorDouble . MultiplyAddEstimate ( TVectorDouble . Create ( - 0.5 ) , x2 , TVectorDouble . One ) ;
17341768 }
17351769 }
1736- else
1770+ else if ( TVectorDouble . LessThanAll ( ax , TVectorDouble . Create ( 5000000.0 ) ) )
17371771 {
17381772 // at least one element is: |x| > (pi / 4) -or- infinite -or- nan
17391773 ( TVectorDouble r , TVectorDouble rr , TVectorInt64 region ) = SinCosReduce < TVectorDouble , TVectorInt64 > ( ax ) ;
17401774
17411775 TVectorDouble sin = SinDoubleLarge ( r , rr ) ;
17421776 TVectorDouble cos = CosDoubleLarge ( r , rr ) ;
17431777
1744- TVectorDouble regionMask = Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ;
1745-
17461778 sinResult = TVectorDouble . ConditionalSelect (
1747- regionMask ,
1779+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ,
17481780 sin , // region 0 or 2
17491781 cos // region 1 or 3
17501782 ) ;
17511783
17521784 cosResult = TVectorDouble . ConditionalSelect (
1753- regionMask ,
1785+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ,
17541786 cos , // region 0 or 2
17551787 sin // region 1 or 3
17561788 ) ;
@@ -1770,51 +1802,64 @@ public static (TVectorDouble Sin, TVectorDouble Cos) SinCosDouble<TVectorDouble,
17701802 ) ;
17711803
17721804 // Propagate the NaN that was passed in
1773- TVectorDouble nanMask = TVectorDouble . IsNaN ( x ) ;
1774-
17751805 sinResult = TVectorDouble . ConditionalSelect (
1776- nanMask ,
1806+ TVectorDouble . IsNaN ( x ) ,
17771807 x ,
17781808 sinResult
17791809 ) ;
17801810
17811811 cosResult = TVectorDouble . ConditionalSelect (
1782- nanMask ,
1812+ TVectorDouble . IsNaN ( x ) ,
17831813 x ,
17841814 cosResult
17851815 ) ;
17861816
17871817 // Return NaN for infinity
1788- TVectorDouble infinityMask = TVectorDouble . IsPositiveInfinity ( ax ) ;
1789-
17901818 sinResult = TVectorDouble . ConditionalSelect (
1791- infinityMask ,
1819+ TVectorDouble . IsPositiveInfinity ( ax ) ,
17921820 TVectorDouble . Create ( double . NaN ) ,
17931821 sinResult
17941822 ) ;
17951823
17961824 cosResult = TVectorDouble . ConditionalSelect (
1797- infinityMask ,
1825+ TVectorDouble . IsPositiveInfinity ( ax ) ,
17981826 TVectorDouble . Create ( double . NaN ) ,
17991827 cosResult
18001828 ) ;
18011829 }
1802-
1803- TVectorDouble argNotSmallerMask = Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ;
1830+ else
1831+ {
1832+ return ScalarFallback ( x ) ;
1833+ }
18041834
18051835 sinResult = TVectorDouble . ConditionalSelect (
1806- argNotSmallerMask ,
1836+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ,
18071837 sinResult , // for elements: |x| >= 2^-27, infinity, or NaN
18081838 x // for elements: 2^-27 > |x|
18091839 ) ;
18101840
18111841 cosResult = TVectorDouble . ConditionalSelect (
1812- argNotSmallerMask ,
1842+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ,
18131843 cosResult , // for elements: |x| >= 2^-27, infinity, or NaN
18141844 TVectorDouble . One // for elements: 2^-27 > |x|
18151845 ) ;
18161846
18171847 return ( sinResult , cosResult ) ;
1848+
1849+ static ( TVectorDouble Sin , TVectorDouble Cos ) ScalarFallback ( TVectorDouble x )
1850+ {
1851+ TVectorDouble sinResult = TVectorDouble . Zero ;
1852+ TVectorDouble cosResult = TVectorDouble . Zero ;
1853+
1854+ for ( int i = 0 ; i < TVectorDouble . Count ; i ++ )
1855+ {
1856+ ( double sinScalar , double cosScalar ) = double . SinCos ( x [ i ] ) ;
1857+ sinResult = sinResult . WithElement ( i , sinScalar ) ;
1858+ cosResult = cosResult . WithElement ( i , cosScalar ) ;
1859+ }
1860+
1861+ return ( sinResult , cosResult ) ;
1862+ }
18181863 }
18191864
18201865 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -1886,7 +1931,7 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle<TVectorSingle,
18861931 cosResult = TVectorSingle . MultiplyAddEstimate ( TVectorSingle . Create ( - 0.5f ) , x2 , TVectorSingle . One ) ;
18871932 }
18881933 }
1889- else
1934+ else if ( TVectorSingle . LessThanAll ( ax , TVectorSingle . Create ( 5000000.0f ) ) )
18901935 {
18911936 // at least one element is: |x| > (pi / 4) -or- infinite -or- nan
18921937
@@ -1907,48 +1952,46 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle<TVectorSingle,
19071952 }
19081953
19091954 // Propagate the NaN that was passed in
1910- TVectorSingle nanMask = TVectorSingle . IsNaN ( x ) ;
1911-
19121955 sinResult = TVectorSingle . ConditionalSelect (
1913- nanMask ,
1956+ TVectorSingle . IsNaN ( x ) ,
19141957 x ,
19151958 sinResult
19161959 ) ;
19171960
19181961 cosResult = TVectorSingle . ConditionalSelect (
1919- nanMask ,
1962+ TVectorSingle . IsNaN ( x ) ,
19201963 x ,
19211964 cosResult
19221965 ) ;
19231966
19241967 // Return NaN for infinity
1925- TVectorSingle infinityMask = TVectorSingle . IsPositiveInfinity ( ax ) ;
1926-
19271968 sinResult = TVectorSingle . ConditionalSelect (
1928- infinityMask ,
1969+ TVectorSingle . IsPositiveInfinity ( ax ) ,
19291970 TVectorSingle . Create ( float . NaN ) ,
19301971 sinResult
19311972 ) ;
19321973
19331974 cosResult = TVectorSingle . ConditionalSelect (
1934- infinityMask ,
1975+ TVectorSingle . IsPositiveInfinity ( ax ) ,
19351976 TVectorSingle . Create ( float . NaN ) ,
19361977 cosResult
19371978 ) ;
19381979
19391980 return ( sinResult , cosResult ) ;
19401981 }
1941-
1942- TVectorSingle argNotSmallerMask = Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ;
1982+ else
1983+ {
1984+ return ScalarFallback ( x ) ;
1985+ }
19431986
19441987 sinResult = TVectorSingle . ConditionalSelect (
1945- argNotSmallerMask ,
1988+ Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ,
19461989 sinResult , // for elements: |x| >= 2^-27, infinity, or NaN
19471990 x // for elements: 2^-27 > |x|
19481991 ) ;
19491992
19501993 cosResult = TVectorSingle . ConditionalSelect (
1951- argNotSmallerMask ,
1994+ Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ,
19521995 cosResult , // for elements: |x| >= 2^-27, infinity, or NaN
19531996 TVectorSingle . One // for elements: 2^-27 > |x|
19541997 ) ;
@@ -1963,16 +2006,14 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle<TVectorSingle,
19632006 TVectorDouble sin = SinSinglePoly ( r ) ;
19642007 TVectorDouble cos = CosSingleLarge ( r ) ;
19652008
1966- TVectorDouble regionMask = Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ;
1967-
19682009 TVectorDouble sinResult = TVectorDouble . ConditionalSelect (
1969- regionMask ,
2010+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ,
19702011 sin , // region 0 or 2
19712012 cos // region 1 or 3
19722013 ) ;
19732014
19742015 TVectorDouble cosResult = TVectorDouble . ConditionalSelect (
1975- regionMask ,
2016+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ,
19762017 cos , // region 0 or 2
19772018 sin // region 1 or 3
19782019 ) ;
@@ -1993,6 +2034,21 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle<TVectorSingle,
19932034
19942035 return ( sinResult , cosResult ) ;
19952036 }
2037+
2038+ static ( TVectorSingle Sin , TVectorSingle Cos ) ScalarFallback ( TVectorSingle x )
2039+ {
2040+ TVectorSingle sinResult = TVectorSingle . Zero ;
2041+ TVectorSingle cosResult = TVectorSingle . Zero ;
2042+
2043+ for ( int i = 0 ; i < TVectorSingle . Count ; i ++ )
2044+ {
2045+ ( float sinScalar , float cosScalar ) = float . SinCos ( x [ i ] ) ;
2046+ sinResult = sinResult . WithElement ( i , sinScalar ) ;
2047+ cosResult = cosResult . WithElement ( i , cosScalar ) ;
2048+ }
2049+
2050+ return ( sinResult , cosResult ) ;
2051+ }
19962052 }
19972053
19982054 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -2076,7 +2132,7 @@ public static TVectorDouble SinDouble<TVectorDouble, TVectorInt64>(TVectorDouble
20762132 result = TVectorDouble . MultiplyAddEstimate ( TVectorDouble . Create ( - 0.16666666666666666 ) , x3 , x ) ;
20772133 }
20782134 }
2079- else
2135+ else if ( TVectorDouble . LessThanAll ( ax , TVectorDouble . Create ( 5000000.0 ) ) )
20802136 {
20812137 // at least one element is: |x| > (pi / 4) -or- infinite -or- nan
20822138 ( TVectorDouble r , TVectorDouble rr , TVectorInt64 region ) = SinCosReduce < TVectorDouble , TVectorInt64 > ( ax ) ;
@@ -2112,12 +2168,29 @@ public static TVectorDouble SinDouble<TVectorDouble, TVectorInt64>(TVectorDouble
21122168 result
21132169 ) ;
21142170 }
2171+ else
2172+ {
2173+ return ScalarFallback ( x ) ;
2174+ }
21152175
21162176 return TVectorDouble . ConditionalSelect (
21172177 Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ,
21182178 result , // for elements: |x| >= 2^-27, infinity, or NaN
21192179 x // for elements: 2^-27 > |x|
21202180 ) ;
2181+
2182+ static TVectorDouble ScalarFallback ( TVectorDouble x )
2183+ {
2184+ TVectorDouble result = TVectorDouble . Zero ;
2185+
2186+ for ( int i = 0 ; i < TVectorDouble . Count ; i ++ )
2187+ {
2188+ double scalar = double . Sin ( x [ i ] ) ;
2189+ result = result . WithElement ( i , scalar ) ;
2190+ }
2191+
2192+ return result ;
2193+ }
21212194 }
21222195
21232196 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -2215,7 +2288,7 @@ public static TVectorSingle SinSingle<TVectorSingle, TVectorInt32, TVectorDouble
22152288 result = TVectorSingle . MultiplyAddEstimate ( TVectorSingle . Create ( - 0.16666667f ) , x3 , x ) ;
22162289 }
22172290 }
2218- else
2291+ else if ( TVectorSingle . LessThanAll ( ax , TVectorSingle . Create ( 5000000.0f ) ) )
22192292 {
22202293 // at least one element is: |x| > (pi / 4) -or- infinite -or- nan
22212294
@@ -2247,6 +2320,10 @@ public static TVectorSingle SinSingle<TVectorSingle, TVectorInt32, TVectorDouble
22472320 result
22482321 ) ;
22492322 }
2323+ else
2324+ {
2325+ return ScalarFallback ( x ) ;
2326+ }
22502327
22512328 return TVectorSingle . ConditionalSelect (
22522329 Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ,
@@ -2277,6 +2354,19 @@ static TVectorDouble CoreImpl(TVectorDouble x)
22772354 - result // negative in region 0 or 2, positive in region 1 or 3
22782355 ) ;
22792356 }
2357+
2358+ static TVectorSingle ScalarFallback ( TVectorSingle x )
2359+ {
2360+ TVectorSingle result = TVectorSingle . Zero ;
2361+
2362+ for ( int i = 0 ; i < TVectorSingle . Count ; i ++ )
2363+ {
2364+ float scalar = float . Sin ( x [ i ] ) ;
2365+ result = result . WithElement ( i , scalar ) ;
2366+ }
2367+
2368+ return result ;
2369+ }
22802370 }
22812371
22822372 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
0 commit comments