1818#include " src/__support/macros/null_check.h" // LIBC_CRASH_ON_VALUE
1919#include " src/__support/macros/optimization.h" // LIBC_UNLIKELY
2020#include " src/__support/math_extras.h"
21+ #include " src/__support/libc_assert.h"
2122
2223#include " fx_rep.h"
2324
@@ -229,12 +230,12 @@ LIBC_INLINE long accum nrstep(long accum d, long accum x0) {
229230 return v;
230231}
231232
232- /* Divide the two integers and return a fixed_point value
233- *
234- * For reference, see:
235- * https://en.wikipedia.org/wiki/Division_algorithm#Newton%E2%80%93Raphson_division
236- * https://stackoverflow.com/a/9231996
237- */
233+ // Divide the two integers and return a fixed_point value
234+ //
235+ // For reference, see:
236+ // https://en.wikipedia.org/wiki/Division_algorithm#Newton%E2%80%93Raphson_division
237+ // https://stackoverflow.com/a/9231996
238+
238239template <typename XType> LIBC_INLINE constexpr XType divi (int n, int d) {
239240 // If the value of the second operand of the / operator is zero, the
240241 // behavior is undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
@@ -243,39 +244,36 @@ template <typename XType> LIBC_INLINE constexpr XType divi(int n, int d) {
243244 if (LIBC_UNLIKELY (n == 0 )) {
244245 return FXRep<XType>::ZERO ();
245246 }
246- bool result_is_negative = (n < 0 ) ^ (d < 0 );
247+ bool result_is_negative = (( n < 0 ) != (d < 0 ) );
247248
248249 unsigned int nv = static_cast <unsigned int >(n < 0 ? -n : n);
249250 unsigned int dv = static_cast <unsigned int >(d < 0 ? -d : d);
250251 unsigned int clz = cpp::countl_zero<unsigned int >(dv) - 1 ;
251252 unsigned long int scaled_val = dv << clz;
252- /* Scale denominator to be in the range of [0.5,1] */
253+ // Scale denominator to be in the range of [0.5,1]
253254 FXBits<long accum> d_scaled{scaled_val};
254255 unsigned long int scaled_val_n = nv << clz;
255- /* Scale the numerator as much as the denominator to maintain correctness of
256- * the original equation
257- */
256+ // Scale the numerator as much as the denominator to maintain correctness of
257+ // the original equation
258258 FXBits<long accum> n_scaled{scaled_val_n};
259259 long accum n_scaled_val = n_scaled.get_val ();
260260 long accum d_scaled_val = d_scaled.get_val ();
261- /* x0 = (48/17) - (32/17) * d_n */
262- long accum a = 2 .8235lk; /* 48/17 */
263- long accum b = 1 .8823lk; /* 32/17 */
264- /* Error of the initial approximation, as derived
265- * from the wikipedia article is
266- * E0 = 1/17 = 0.059 (5.9%)
267- */
261+ // x0 = (48/17) - (32/17) * d_n
262+ long accum a = 0x2 .d89d89d8p0lk ; // 48/17 = 2.8235294...
263+ long accum b = 0x1 .e1e1e1e1p0lk ; // 32/17 = 1.8823529...
264+ // Error of the initial approximation, as derived
265+ // from the wikipedia article is
266+ // E0 = 1/17 = 0.059 (5.9%)
268267 long accum initial_approx = a - (b * d_scaled_val);
269- /* Each newton-raphson iteration will square the error, due
270- * to quadratic convergence. So,
271- * E1 = (0.059)^2 = 0.0034
272- */
268+ // Since, 0.5 <= d_scaled_val <= 1.0, 0.9412 <= initial_approx <= 1.88235
269+ LIBC_ASSERT ((initial_approx >= 0x0 .78793dd9p0lk) && (initial_approx <= 0x1 .f0f0d845p0lk ));
270+ // Each newton-raphson iteration will square the error, due
271+ // to quadratic convergence. So,
272+ // E1 = (0.059)^2 = 0.0034
273273 long accum val = nrstep (d_scaled_val, initial_approx);
274- /* E2 = 0.0000121 */
275- val = nrstep (d_scaled_val, val);
276- /* E3 = 1.468e−10 */
274+ // E2 = 0.0000121
277275 val = nrstep (d_scaled_val, val);
278- /* E4 = 2.155e−20 */
276+ // E3 = 1.468e−10
279277 val = nrstep (d_scaled_val, val);
280278
281279 long accum res = n_scaled_val * val;
@@ -288,7 +286,7 @@ template <typename XType> LIBC_INLINE constexpr XType divi(int n, int d) {
288286 long accum max_val = static_cast <long accum>(FXRep<XType>::MAX ());
289287 long accum min_val = static_cast <long accum>(FXRep<XType>::MIN ());
290288
291- /* Per clause 7.18a.6.1, saturate values on overflow */
289+ // Per clause 7.18a.6.1, saturate values on overflow
292290 if (res > max_val) {
293291 return FXRep<XType>::MAX ();
294292 } else if (res < min_val) {
0 commit comments