@@ -74,40 +74,45 @@ namespace eve
7474 namespace detail
7575 {
7676 template <eve::floating_value T, callable_options O>
77- EVE_FORCEINLINE constexpr auto cbrt_ (EVE_REQUIRES(cpu_), O const & , T x) noexcept
77+ EVE_FORCEINLINE constexpr auto cbrt_ (EVE_REQUIRES(cpu_), O const & o , T x) noexcept
7878 {
79- using vt_t = element_type_t <T>;
80- auto test0 = is_eqz (x) || is_not_finite (x);
81- if constexpr ( eve::scalar_value<T> )
82- if ( test0 ) return x;
83- constexpr vt_t factor[5 ] = {0.6299605249474365823836 ,
84- 0.793700525984099737376 ,
85- 1.0 ,
86- 1.2599210498948731647672 ,
87- 1.587401051968199474751 };
88- auto ax = eve::abs (x);
89- auto test = is_less (eve::abs (x), T (100 ) * smallestposval (eve::as<T>()));
90- ax = ldexp[test](ax, 54 );
91- /* Reduce x. xm now is an range [0.5, 1.0]. */
92- auto [xm, xe] = ifrexp[raw](ax);
93- T u;
94- if constexpr ( std::is_same_v<vt_t , double > )
95- u = eve::reverse_horner (xm, T (0x1 .6b69cba168ff2p-2 ), T (0x1 .8218dde9028b4p+0 ), T (-0x1 .0eb8277cd8d5dp+1 )
96- , T (0x1 .39350adad51ecp+1 ), T (-0x1 .d5ae6cfa20f0cp +0 )
97- , T (0x1 .91e2a6fe7e984p-1 ), T (-0x1 .29801e893366dp-3 ));
98- else if constexpr ( std::is_same_v<vt_t , float > )
99- u = eve::reverse_horner (xm, T (0x1 .f87bc4p -2f ), T (0x1 .6527f4p-1f ), T (-0x1 .88324ap-3f ));
100- auto t2 = sqr (u) * u;
101- u *= fma (xm, T (2 ), t2) / fma (T (2 ), t2, xm);
79+ if constexpr (std::same_as<eve::element_type_t <T>, eve::float16_t >)
80+ return eve::detail::apply_fp16_as_fp32 (eve::cbrt[o], x);
81+ else
82+ {
83+ using vt_t = element_type_t <T>;
84+ auto test0 = is_eqz (x) || is_not_finite (x);
85+ if constexpr ( eve::scalar_value<T> )
86+ if ( test0 ) return x;
87+ constexpr vt_t factor[5 ] = {0.6299605249474365823836 ,
88+ 0.793700525984099737376 ,
89+ 1.0 ,
90+ 1.2599210498948731647672 ,
91+ 1.587401051968199474751 };
92+ auto ax = eve::abs (x);
93+ auto test = is_less (eve::abs (x), T (100 ) * smallestposval (eve::as<T>()));
94+ ax = ldexp[test](ax, 54 );
95+ /* Reduce x. xm now is an range [0.5, 1.0]. */
96+ auto [xm, xe] = ifrexp[raw](ax);
97+ T u;
98+ if constexpr ( std::is_same_v<vt_t , double > )
99+ u = eve::reverse_horner (xm, T (0x1 .6b69cba168ff2p-2 ), T (0x1 .8218dde9028b4p+0 ), T (-0x1 .0eb8277cd8d5dp+1 )
100+ , T (0x1 .39350adad51ecp+1 ), T (-0x1 .d5ae6cfa20f0cp +0 )
101+ , T (0x1 .91e2a6fe7e984p-1 ), T (-0x1 .29801e893366dp-3 ));
102+ else if constexpr ( std::is_same_v<vt_t , float > )
103+ u = eve::reverse_horner (xm, T (0x1 .f87bc4p -2f ), T (0x1 .6527f4p-1f ), T (-0x1 .88324ap-3f ));
104+ auto t2 = sqr (u) * u;
105+ u *= fma (xm, T (2 ), t2) / fma (T (2 ), t2, xm);
102106
103- if constexpr ( eve::scalar_value<T> ) u *= factor[2 + xe % 3 ];
104- else u *= gather (&factor[0 ], 2 + xe - (xe / 3 ) * 3 );
105- u = minus[is_ltz (x)](u);
106- if constexpr ( eve::scalar_value<T> ) xe = add[test](int (xe) / 3 , -18 );
107- else xe = add[test](xe / 3 , -18 );
108- auto z = ldexp (u, xe);
109- if constexpr ( eve::scalar_value<T> ) return z;
110- else return if_else (test0, x, z);
107+ if constexpr ( eve::scalar_value<T> ) u *= factor[2 + xe % 3 ];
108+ else u *= gather (&factor[0 ], 2 + xe - (xe / 3 ) * 3 );
109+ u = minus[is_ltz (x)](u);
110+ if constexpr ( eve::scalar_value<T> ) xe = add[test](int (xe) / 3 , -18 );
111+ else xe = add[test](xe / 3 , -18 );
112+ auto z = ldexp (u, xe);
113+ if constexpr ( eve::scalar_value<T> ) return z;
114+ else return if_else (test0, x, z);
115+ }
111116 }
112117 }
113118}
0 commit comments