Skip to content

Commit c614888

Browse files
committed
[libc] comments, remove extra iterations, and misc changes
Signed-off-by: Shreeyash Pandey <[email protected]>
1 parent cfe5122 commit c614888

File tree

2 files changed

+30
-33
lines changed

2 files changed

+30
-33
lines changed

libc/src/__support/fixed_point/fx_bits.h

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
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+
238239
template <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) {

libc/test/src/stdfix/DivITest.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,15 @@ class DivITest : public LIBC_NAMESPACE::testing::Test {
5151
EXPECT_EQ(func(0, -10), 0.r);
5252
EXPECT_EQ(func(-(1 << FRACT_FBIT), 1 << FRACT_FBIT), FRACT_MIN);
5353
EXPECT_EQ(func((1 << FRACT_FBIT) - 1, 1 << FRACT_FBIT), FRACT_MAX);
54-
/* From Section 7.18a.6.1, functions returning a fixed-point value, the
55-
* return value is saturated on overflow. */
54+
// From Section 7.18a.6.1, functions returning a fixed-point value, the
55+
// return value is saturated on overflow.
5656
EXPECT_EQ(func(INT_MAX, INT_MAX), FRACT_MAX);
5757
EXPECT_LT(func(INT_MAX - 1, INT_MAX) - 0.99999999r, epsilon);
5858
EXPECT_EQ(func(INT_MIN, INT_MAX), FRACT_MIN);
59-
/* Expecting 0 here as fract is not precise enough to
60-
* handle 1/INT_MAX
61-
*/
59+
// Expecting 0 here as fract is not precise enough to
60+
// handle 1/INT_MAX
6261
EXPECT_LT(func(1, INT_MAX) - 0.r, epsilon);
63-
/* This results in 1.1739, which should be saturated to FRACT_MAX */
62+
// This results in 1.1739, which should be saturated to FRACT_MAX
6463
EXPECT_EQ(func(27, 23), FRACT_MAX);
6564
}
6665
};

0 commit comments

Comments
 (0)