[libc-commits] [libc] [llvm] [libc] Move printf long double to simple calc (PR #75414)
Guillaume Chatelet via libc-commits
libc-commits at lists.llvm.org
Thu Jan 11 08:24:28 PST 2024
================
@@ -567,197 +574,264 @@ class FloatToString {
}
LIBC_INLINE constexpr size_t get_positive_blocks() {
- if (exponent >= -FRACTION_LEN) {
- const uint32_t idx =
- exponent < 0
- ? 0
- : static_cast<uint32_t>(exponent + (IDX_SIZE - 1)) / IDX_SIZE;
- const uint32_t len =
- internal::length_for_num(idx * IDX_SIZE, FRACTION_LEN);
- return len;
- } else {
+ if (exponent < -FRACTION_LEN)
return 0;
- }
+ const uint32_t idx =
+ exponent < 0
+ ? 0
+ : static_cast<uint32_t>(exponent + (IDX_SIZE - 1)) / IDX_SIZE;
+ return internal::length_for_num(idx * IDX_SIZE, FRACTION_LEN);
}
// This takes the index of a block after the decimal point (a negative block)
// and return if it's sure that all of the digits after it are zero.
- LIBC_INLINE constexpr bool is_lowest_block(size_t block_index) {
+ LIBC_INLINE constexpr bool is_lowest_block(size_t negative_block_index) {
#ifdef LIBC_COPT_FLOAT_TO_STR_NO_TABLE
- return false;
+ // The decimal representation of 2**(-i) will have exactly i digits after
+ // the decimal point.
+ int num_requested_digits =
+ static_cast<int>((negative_block_index + 1) * BLOCK_SIZE);
+
+ return num_requested_digits > -exponent;
#else
const int32_t idx = -exponent / IDX_SIZE;
- const size_t p = POW10_OFFSET_2[idx] + block_index - MIN_BLOCK_2[idx];
+ const size_t p =
+ POW10_OFFSET_2[idx] + negative_block_index - MIN_BLOCK_2[idx];
// If the remaining digits are all 0, then this is the lowest block.
return p >= POW10_OFFSET_2[idx + 1];
#endif
}
LIBC_INLINE constexpr size_t zero_blocks_after_point() {
#ifdef LIBC_COPT_FLOAT_TO_STR_NO_TABLE
+ if (exponent < -FRACTION_LEN) {
+ const int pos_exp = -exponent - 1;
+ const uint32_t pos_idx =
+ static_cast<uint32_t>(pos_exp + (IDX_SIZE - 1)) / IDX_SIZE;
+ const int32_t pos_len = ((internal::ceil_log10_pow2(pos_idx * IDX_SIZE) -
+ internal::ceil_log10_pow2(FRACTION_LEN + 1)) /
+ BLOCK_SIZE) -
+ 1;
+ return static_cast<uint32_t>(pos_len > 0 ? pos_len : 0);
+ }
return 0;
- // TODO (michaelrj): Find a good algorithm for this that doesn't use a
- // table.
#else
return MIN_BLOCK_2[-exponent / IDX_SIZE];
#endif
}
};
-#ifndef LIBC_LONG_DOUBLE_IS_FLOAT64
+#if !defined(LIBC_LONG_DOUBLE_IS_FLOAT64) && \
+ !defined(LIBC_COPT_FLOAT_TO_STR_NO_SPECIALIZE_LD)
// --------------------------- LONG DOUBLE FUNCTIONS ---------------------------
-template <>
-LIBC_INLINE constexpr size_t FloatToString<long double>::get_positive_blocks() {
- if (exponent >= -FRACTION_LEN) {
- const uint32_t idx =
- exponent < 0
- ? 0
- : static_cast<uint32_t>(exponent + (IDX_SIZE - 1)) / IDX_SIZE;
- const uint32_t len = internal::length_for_num(idx * IDX_SIZE, FRACTION_LEN);
- return len;
- } else {
- return 0;
+template <> class FloatToString<long double> {
+ fputil::FPBits<long double> float_bits;
+ bool is_negative = 0;
+ int exponent = 0;
+ FPBits::StorageType mantissa = 0;
+
+ static constexpr int FRACTION_LEN = fputil::FPBits<long double>::FRACTION_LEN;
+ static constexpr int EXP_BIAS = fputil::FPBits<long double>::EXP_BIAS;
+
+ static constexpr size_t FLOAT_AS_INT_WIDTH =
+ internal::div_ceil(fputil::FPBits<long double>::MAX_BIASED_EXPONENT -
+ FPBits::EXP_BIAS,
+ 64) *
----------------
gchatelet wrote:
Can we introduce a constant for `64`.
https://github.com/llvm/llvm-project/pull/75414
More information about the libc-commits
mailing list