@@ -52,80 +52,81 @@ namespace cephes {
52
52
53
53
namespace detail {
54
54
55
- constexpr double CBRT2 = 1.2599210498948731647672 ;
56
- constexpr double CBRT4 = 1.5874010519681994747517 ;
57
- constexpr double CBRT2I = 0.79370052598409973737585 ;
58
- constexpr double CBRT4I = 0.62996052494743658238361 ;
55
+ inline constexpr double CBRT2 = 1.2599210498948731647672 ;
56
+ inline constexpr double CBRT4 = 1.5874010519681994747517 ;
57
+ inline constexpr double CBRT2I = 0.79370052598409973737585 ;
58
+ inline constexpr double CBRT4I = 0.62996052494743658238361 ;
59
59
60
- XSF_HOST_DEVICE inline double cbrt (double x) {
61
- int e, rem, sign;
62
- double z;
60
+ }
63
61
64
- if (!std::isfinite (x)) {
65
- return x;
66
- }
67
- if (x == 0 ) {
68
- return (x);
69
- }
70
- if (x > 0 ) {
71
- sign = 1 ;
72
- } else {
73
- sign = -1 ;
74
- x = -x;
75
- }
62
+ XSF_HOST_DEVICE inline double cbrt (double x) {
63
+ int e, rem, sign;
64
+ double z;
76
65
77
- z = x;
78
- /* extract power of 2, leaving
79
- * mantissa between 0.5 and 1
80
- */
81
- x = std::frexp (x, &e);
66
+ if (!std::isfinite (x)) {
67
+ return x;
68
+ }
69
+ if (x == 0 ) {
70
+ return (x);
71
+ }
72
+ if (x > 0 ) {
73
+ sign = 1 ;
74
+ } else {
75
+ sign = -1 ;
76
+ x = -x;
77
+ }
78
+
79
+ z = x;
80
+ /* extract power of 2, leaving
81
+ * mantissa between 0.5 and 1
82
+ */
83
+ x = std::frexp (x, &e);
84
+
85
+ /* Approximate cube root of number between .5 and 1,
86
+ * peak relative error = 9.2e-6
87
+ */
88
+ x = (((-1.3466110473359520655053e-1 * x + 5.4664601366395524503440e-1 ) * x - 9.5438224771509446525043e-1 ) *
89
+ x +
90
+ 1.1399983354717293273738e0 ) *
91
+ x +
92
+ 4.0238979564544752126924e-1 ;
93
+
94
+ /* exponent divided by 3 */
95
+ if (e >= 0 ) {
96
+ rem = e;
97
+ e /= 3 ;
98
+ rem -= 3 * e;
99
+ if (rem == 1 ) {
100
+ x *= detail::CBRT2;
101
+ } else if (rem == 2 ) {
102
+ x *= detail::CBRT4;
103
+ }
104
+ }
105
+ /* argument less than 1 */
106
+ else {
107
+ e = -e;
108
+ rem = e;
109
+ e /= 3 ;
110
+ rem -= 3 * e;
111
+ if (rem == 1 ) {
112
+ x *= detail::CBRT2I;
113
+ } else if (rem == 2 ) {
114
+ x *= detail::CBRT4I;
115
+ }
116
+ e = -e;
117
+ }
82
118
83
- /* Approximate cube root of number between .5 and 1,
84
- * peak relative error = 9.2e-6
85
- */
86
- x = (((-1.3466110473359520655053e-1 * x + 5.4664601366395524503440e-1 ) * x - 9.5438224771509446525043e-1 ) *
87
- x +
88
- 1.1399983354717293273738e0 ) *
89
- x +
90
- 4.0238979564544752126924e-1 ;
119
+ /* multiply by power of 2 */
120
+ x = std::ldexp (x, e);
121
+
122
+ /* Newton iteration */
123
+ x -= (x - (z / (x * x))) * 0.33333333333333333333 ;
124
+ x -= (x - (z / (x * x))) * 0.33333333333333333333 ;
91
125
92
- /* exponent divided by 3 */
93
- if (e >= 0 ) {
94
- rem = e;
95
- e /= 3 ;
96
- rem -= 3 * e;
97
- if (rem == 1 ) {
98
- x *= CBRT2;
99
- } else if (rem == 2 ) {
100
- x *= CBRT4;
101
- }
102
- }
103
- /* argument less than 1 */
104
- else {
105
- e = -e;
106
- rem = e;
107
- e /= 3 ;
108
- rem -= 3 * e;
109
- if (rem == 1 ) {
110
- x *= CBRT2I;
111
- } else if (rem == 2 ) {
112
- x *= CBRT4I;
113
- }
114
- e = -e;
115
- }
116
-
117
- /* multiply by power of 2 */
118
- x = std::ldexp (x, e);
119
-
120
- /* Newton iteration */
121
- x -= (x - (z / (x * x))) * 0.33333333333333333333 ;
122
- x -= (x - (z / (x * x))) * 0.33333333333333333333 ;
123
-
124
- if (sign < 0 )
125
- x = -x;
126
- return (x);
127
- }
128
- } // namespace detail
126
+ if (sign < 0 )
127
+ x = -x;
128
+ return (x);
129
+ }
129
130
130
131
} // namespace cephes
131
132
} // namespace xsf
0 commit comments