|
12 | 12 | #include "include/llvm-libc-macros/stdfix-macros.h" |
13 | 13 | #include "src/__support/CPP/bit.h" |
14 | 14 | #include "src/__support/CPP/type_traits.h" |
15 | | -#include "src/__support/macros/attributes.h" // LIBC_INLINE |
| 15 | +#include "src/__support/macros/attributes.h" // LIBC_INLINE |
16 | 16 | #include "src/__support/macros/config.h" |
17 | 17 | #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY |
18 | 18 | #include "src/__support/math_extras.h" |
@@ -163,12 +163,23 @@ template <typename T> LIBC_INLINE constexpr T round(T x, int n) { |
163 | 163 | return bit_and((x + round_bit), rounding_mask); |
164 | 164 | } |
165 | 165 |
|
166 | | -// u?int_fx_t --> Fixed point |
| 166 | +// (u)?int_fx_t --> Fixed point |
167 | 167 | template <typename T, typename XType> LIBC_INLINE constexpr T fxbits(XType x) { |
168 | | - // Example: rbits(0x2000) where fract has 15 fractional bits, |
169 | | - // 0x2000 --> 0010 0000 0000 0000 --> 0.010 0000 0000 0000 = 0.25 |
| 168 | + using FXRep = FXRep<T>; |
| 169 | + |
| 170 | + // Shift number by FX_IBITS so the bits are in the right spot. |
| 171 | + // If the number is negative we need to make it positive, shift it and then |
| 172 | + // renegate it to get the correct value. |
| 173 | + if (cpp::is_signed_v<XType> && |
| 174 | + ((1 << (FXRep::TOTAL_LEN - 1)) & x)) { |
| 175 | + x = -x; |
| 176 | + x >>= FXRep::INTEGRAL_LEN; |
| 177 | + x = -x; |
| 178 | + } else { |
| 179 | + x >>= FXRep::INTEGRAL_LEN; |
| 180 | + } |
170 | 181 |
|
171 | | - return cpp::bit_cast<T, XType>(x); |
| 182 | + return cpp::bit_cast<T, XType>(x); |
172 | 183 | } |
173 | 184 | } // namespace fixed_point |
174 | 185 | } // namespace LIBC_NAMESPACE_DECL |
|
0 commit comments