Skip to content

Commit 040e833

Browse files
committed
[libc][stdfix] add a couple more tests and error info for divi
Signed-off-by: Shreeyash Pandey <[email protected]>
1 parent f54208e commit 040e833

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

libc/src/__support/fixed_point/fx_bits.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,21 @@ template <typename XType> LIBC_INLINE constexpr XType divi(int n, int d) {
265265
/* x0 = (48/17) - (32/17) * d_n */
266266
long accum a = 2.8235lk; /* 48/17 */
267267
long accum b = 1.8823lk; /* 32/17 */
268+
/* Error of the initial approximation, as derived
269+
* from the wikipedia article is
270+
* E0 = 1/17 = 0.059 (5.9%)
271+
*/
268272
long accum initial_approx = a - (b * d_scaled_val);
273+
/* Each newton-raphson iteration will square the error, due
274+
* to quadratic convergence. So,
275+
* E1 = (0.059)^2 = 0.0034
276+
*/
269277
long accum val = nrstep(d_scaled_val, initial_approx);
278+
/* E2 = 0.0000121 */
270279
val = nrstep(d_scaled_val, val);
280+
/* E3 = 1.468e−10 */
271281
val = nrstep(d_scaled_val, val);
282+
/* E4 = 2.155e−20 */
272283
val = nrstep(d_scaled_val, val);
273284
long accum res = n_scaled_val * val;
274285
if (d_is_signed) {

libc/test/src/stdfix/DivITest.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111
#include "src/__support/fixed_point/fx_rep.h"
1212
#include "test/UnitTest/Test.h"
1313

14-
template <typename XType> XType get_epsilon() {
15-
// TODO: raise error
16-
return 0;
17-
}
14+
template <typename XType> XType get_epsilon() = delete;
1815
template <> fract get_epsilon() { return FRACT_EPSILON; }
1916
template <> unsigned fract get_epsilon() { return UFRACT_EPSILON; }
2017
template <> long fract get_epsilon() { return LFRACT_EPSILON; }
@@ -29,10 +26,10 @@ class DivITest : public LIBC_NAMESPACE::testing::Test {
2926

3027
void testBasic(DivIFunc func) {
3128
XType epsilon = get_epsilon<XType>();
32-
EXPECT_LT((func(2, 3) - 0.666666r), epsilon);
29+
EXPECT_LT((func(2, 3) - 0.666656494140625r), epsilon);
3330
EXPECT_LT((func(3, 4) - 0.75r), epsilon);
34-
EXPECT_LT((func(1043, 2764) - 0.37735r), epsilon);
35-
EXPECT_LT((func(60000, 720293) - 0.083299r), epsilon);
31+
EXPECT_LT((func(1043, 2764) - 0.3773516643r), epsilon);
32+
EXPECT_LT((func(60000, 720293) - 0.08329943509r), epsilon);
3633

3734
EXPECT_EQ(func(128, 256), 0.5r);
3835
EXPECT_EQ(func(1, 2), 0.5r);
@@ -48,9 +45,16 @@ class DivITest : public LIBC_NAMESPACE::testing::Test {
4845

4946
void testSpecial(DivIFunc func) {
5047
EXPECT_EQ(func(0,10), 0.r);
51-
EXPECT_DEATH([func] { func(10, 0); }, WITH_SIGNAL(-1));
48+
EXPECT_EQ(func(0,-10), 0.r);
5249
EXPECT_EQ(func(-32768,32768), FRACT_MIN);
5350
EXPECT_EQ(func(32767,32768), FRACT_MAX);
51+
EXPECT_EQ(func(INT_MAX,INT_MAX), 1.0r);
52+
EXPECT_EQ(func(INT_MAX-1,INT_MAX), 0.99999999r);
53+
EXPECT_EQ(func(INT_MIN,INT_MAX), FRACT_MIN);
54+
/* Expecting 0 here as fract is not precise enough to
55+
* handle 1/INT_MAX
56+
*/
57+
EXPECT_EQ(func(1, INT_MAX), 0.r);
5458
}
5559
};
5660

0 commit comments

Comments
 (0)