Skip to content

Commit 1718201

Browse files
committed
Fix issues with fixed point arrays.
1 parent 71a4e52 commit 1718201

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

libc/src/__support/fixed_point/sqrt.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,25 @@ struct SqrtConfig<unsigned accum> : SqrtConfig<unsigned long fract> {};
5757
// fixed, absolute);
5858
// print("{", coeff(P, 1), "uhr,", coeff(P, 0), "uhr},");
5959
// };
60-
static constexpr unsigned short fract SQRT_FIRST_APPROX[12][2] = {
61-
{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr},
62-
{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr},
63-
{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr},
64-
{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr},
65-
{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr},
66-
{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr},
60+
// Clang is having issues with this array:
61+
// static constexpr unsigned short fract SQRT_FIRST_APPROX[12][2] = {
62+
// {0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr},
63+
// {0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr},
64+
// {0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr},
65+
// {0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr},
66+
// {0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr},
67+
// {0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr},
68+
// };
69+
// We are using their storage type instead.
70+
static constexpr uint8_t SQRT_FIRST_APPROX[12][2] = {
71+
{244, 67}, {221, 74}, {202, 81}, {186, 88}, {176, 93}, {167, 98},
72+
{159, 103}, {153, 107}, {145, 113}, {140, 117}, {132, 124}, {130, 126},
6773
};
6874

6975
} // namespace internal
7076

7177
template <typename T>
72-
LIBC_INLINE constexpr cpp::enable_if_t<
73-
cpp::is_fixed_point_v<T> && cpp::is_unsigned_v<T>, T>
74-
sqrt(T x) {
78+
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, T> sqrt(T x) {
7579
using BitType = typename FXRep<T>::StorageType;
7680
BitType x_bit = cpp::bit_cast<BitType>(x);
7781

@@ -95,8 +99,10 @@ sqrt(T x) {
9599

96100
// Use the leading 4 bits to do look up for sqrt(x).
97101
int index = (x_bit >> (STORAGE_LENGTH - 4)) - 4;
98-
FracType a = static_cast<FracType>(internal::SQRT_FIRST_APPROX[index][0]);
99-
FracType b = static_cast<FracType>(internal::SQRT_FIRST_APPROX[index][1]);
102+
FracType a = static_cast<FracType>(cpp::bit_cast<unsigned short fract>(
103+
internal::SQRT_FIRST_APPROX[index][0]));
104+
FracType b = static_cast<FracType>(cpp::bit_cast<unsigned short fract>(
105+
internal::SQRT_FIRST_APPROX[index][1]));
100106

101107
// Initial approximation step.
102108
// Estimated error bounds: | r - sqrt(x_frac) | < max(1.5 * 2^-11, eps).

libc/test/src/stdfix/SqrtTest.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,24 @@ template <typename T> class SqrtTest : public LIBC_NAMESPACE::testing::Test {
3838
EXPECT_EQ(static_cast<T>(2.0), func(static_cast<T>(4.0)));
3939
}
4040

41-
using StorageType = FXRep<T>::StorageType;
41+
using StorageType = typename FXRep::StorageType;
4242

4343
constexpr size_t COUNT = 255;
4444
constexpr StorageType STEP =
4545
~StorageType(0) / static_cast<StorageType>(COUNT);
46-
constexpr double ERR = static_cast<double>(eps);
47-
for (size_t i = 0, StorageType x = 0; i < COUNT; ++i, x += STEP) {
48-
T v = cpp::bit_cast<T>(x);
46+
constexpr double ERR = 3.0 * static_cast<double>(eps);
47+
StorageType x = 0;
48+
for (size_t i = 0; i < COUNT; ++i, x += STEP) {
49+
T v = LIBC_NAMESPACE::cpp::bit_cast<T>(x);
4950
double v_d = static_cast<double>(v);
5051
double errors = LIBC_NAMESPACE::fputil::abs(
5152
static_cast<double>(func(v)) - LIBC_NAMESPACE::fputil::sqrt(v_d));
52-
ASSERT_LE(errors, ERR);
53+
if (errors > ERR) {
54+
// Print out the failure input and output.
55+
EXPECT_EQ(v, zero);
56+
EXPECT_EQ(func(v), zero);
57+
}
58+
ASSERT_TRUE(errors <= ERR);
5359
}
5460
}
5561
};

0 commit comments

Comments
 (0)