diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h --- a/libc/src/__support/FPUtil/generic/sqrt.h +++ b/libc/src/__support/FPUtil/generic/sqrt.h @@ -136,7 +136,7 @@ } // We compute one more iteration in order to round correctly. - bool lsb = y & 1; // Least significant bit + bool lsb = static_cast(y & 1); // Least significant bit bool rb = false; // Round bit r <<= 2; UIntType tmp = (y << 2) + 1; diff --git a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h --- a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h +++ b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h @@ -123,6 +123,13 @@ return cpp::bit_cast(bits); } + LIBC_INLINE long double get_val() const { + UIntType bits_with_explicit_bit{bits}; + bits_with_explicit_bit &= ~(UIntType(1) << FloatProp::MANTISSA_WIDTH); + bits_with_explicit_bit |= (UIntType(true) << FloatProp::MANTISSA_WIDTH); + return cpp::bit_cast(bits_with_explicit_bit); + } + LIBC_INLINE UIntType uintval() { // We zero the padding bits as they can contain garbage. static constexpr UIntType MASK = diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h --- a/libc/src/__support/UInt.h +++ b/libc/src/__support/UInt.h @@ -77,6 +77,15 @@ val[i] = words[i]; } +#ifdef __SIZEOF_INT128__ + constexpr explicit operator __uint128_t() const { + __uint128_t tmp = val[0]; + if constexpr (Bits >= 128) + tmp += (__uint128_t(val[1]) << 64); + return tmp; + } +#endif // __SIZEOF_INT128__ + constexpr explicit operator uint64_t() const { return val[0]; } constexpr explicit operator uint32_t() const { @@ -468,6 +477,11 @@ return result; } + constexpr UInt operator/=(const UInt &other) { + *this = *this / other; + return *this; + } + constexpr UInt operator%(const UInt &other) const { UInt result(*this); return *result.div(other); @@ -714,8 +728,12 @@ } constexpr UInt &operator++() { - UInt one(1); - add(one); + *this = *this + 1; + return *this; + } + + constexpr UInt &operator--() { + *this = *this - 1; return *this; } diff --git a/libc/src/__support/float_to_string.h b/libc/src/__support/float_to_string.h --- a/libc/src/__support/float_to_string.h +++ b/libc/src/__support/float_to_string.h @@ -202,8 +202,8 @@ cpp::UInt val(large); // TODO: Find a better way to force __uint128_t to be UInt<128> cpp::UInt wide_mant(0); - wide_mant[0] = mantissa & (uint64_t(-1)); - wide_mant[1] = mantissa >> 64; + wide_mant[0] = static_cast(mantissa & UINT64_MAX); + wide_mant[1] = static_cast(mantissa >> 64); val = (val * wide_mant) >> shift_amount; return fast_uint_mod_1e9(val); } diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h --- a/libc/src/__support/str_to_float.h +++ b/libc/src/__support/str_to_float.h @@ -13,6 +13,7 @@ #include "src/__support/CPP/optional.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/dyadic_float.h" #include "src/__support/UInt128.h" #include "src/__support/builtin_wrappers.h" #include "src/__support/common.h" @@ -298,9 +299,10 @@ BitsType msb = final_approx_upper >> (BITS_IN_MANTISSA - 1); BitsType final_mantissa = final_approx_upper >> - (msb + BITS_IN_MANTISSA - - (fputil::FloatProperties::MANTISSA_WIDTH + 3)); - exp2 -= static_cast(1 ^ msb); // same as !msb + static_cast( + msb + BITS_IN_MANTISSA - + (fputil::FloatProperties::MANTISSA_WIDTH + 3)); + exp2 -= static_cast(1) ^ static_cast(msb); // same as !msb if (round == RoundDirection::Nearest) { // Half-way ambiguity @@ -565,7 +567,9 @@ } fputil::FPBits result; - T float_mantissa = static_cast(mantissa); + T float_mantissa = + static_cast(fputil::DyadicFloat<128>(/*sign*/ false, /*exponent*/ 0, + /*mantissa*/ mantissa)); if (exp10 == 0) { result = fputil::FPBits(float_mantissa); @@ -800,7 +804,7 @@ BitsType round_bit_mask = BitsType(1) << (amount_to_shift_right - 1); BitsType sticky_mask = round_bit_mask - 1; - bool round_bit = mantissa & round_bit_mask; + bool round_bit = static_cast(mantissa & round_bit_mask); bool sticky_bit = static_cast(mantissa & sticky_mask) || truncated; if (amount_to_shift_right < NUMBITS) { @@ -810,7 +814,7 @@ } else { mantissa = 0; } - bool least_significant_bit = mantissa & BitsType(1); + bool least_significant_bit = static_cast(mantissa & BitsType(1)); // TODO: check that this rounding behavior is correct. diff --git a/libc/src/stdio/printf_core/char_converter.h b/libc/src/stdio/printf_core/char_converter.h --- a/libc/src/stdio/printf_core/char_converter.h +++ b/libc/src/stdio/printf_core/char_converter.h @@ -19,7 +19,7 @@ namespace printf_core { LIBC_INLINE int convert_char(Writer *writer, const FormatSection &to_conv) { - char c = to_conv.conv_val_raw; + char c = static_cast(to_conv.conv_val_raw); constexpr int string_len = 1; diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h --- a/libc/src/stdio/printf_core/float_dec_converter.h +++ b/libc/src/stdio/printf_core/float_dec_converter.h @@ -598,8 +598,9 @@ const bool trailingZeros = requiredTwos <= 0 || (requiredTwos < 60 && - multiple_of_power_of_2(float_bits.get_explicit_mantissa(), - static_cast(requiredTwos))); + multiple_of_power_of_2( + static_cast(float_bits.get_explicit_mantissa()), + static_cast(requiredTwos))); switch (fputil::get_round()) { case FE_TONEAREST: // Round to nearest, if it's exactly halfway then round to even. @@ -772,8 +773,9 @@ const bool trailingZeros = requiredTwos <= 0 || (requiredTwos < 60 && - multiple_of_power_of_2(float_bits.get_explicit_mantissa(), - static_cast(requiredTwos))); + multiple_of_power_of_2( + static_cast(float_bits.get_explicit_mantissa()), + static_cast(requiredTwos))); switch (fputil::get_round()) { case FE_TONEAREST: // Round to nearest, if it's exactly halfway then round to even. @@ -1020,8 +1022,9 @@ const bool trailingZeros = requiredTwos <= 0 || (requiredTwos < 60 && - multiple_of_power_of_2(float_bits.get_explicit_mantissa(), - static_cast(requiredTwos))); + multiple_of_power_of_2( + static_cast(float_bits.get_explicit_mantissa()), + static_cast(requiredTwos))); switch (fputil::get_round()) { case FE_TONEAREST: // Round to nearest, if it's exactly halfway then round to even. @@ -1147,7 +1150,8 @@ float_bits); } } else { - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; + fputil::FPBits::UIntType float_raw = + static_cast::UIntType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); if (!float_bits.is_inf_or_nan()) { return convert_float_decimal_typed(writer, to_conv, float_bits); @@ -1167,7 +1171,8 @@ float_bits); } } else { - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; + fputil::FPBits::UIntType float_raw = + static_cast::UIntType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); if (!float_bits.is_inf_or_nan()) { return convert_float_dec_exp_typed(writer, to_conv, float_bits); @@ -1187,7 +1192,8 @@ float_bits); } } else { - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; + fputil::FPBits::UIntType float_raw = + static_cast::UIntType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); if (!float_bits.is_inf_or_nan()) { return convert_float_dec_auto_typed(writer, to_conv, float_bits); diff --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h --- a/libc/src/stdio/printf_core/float_hex_converter.h +++ b/libc/src/stdio/printf_core/float_hex_converter.h @@ -51,7 +51,8 @@ } else { mantissa_width = fputil::MantissaWidth::VALUE; exponent_bias = fputil::FPBits::EXPONENT_BIAS; - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; + fputil::FPBits::UIntType float_raw = + static_cast::UIntType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); is_negative = float_bits.get_sign(); exponent = float_bits.get_exponent(); @@ -146,8 +147,9 @@ size_t mant_cur = mant_len; size_t first_non_zero = 1; for (; mant_cur > 0; --mant_cur, mantissa /= 16) { - char new_digit = ((mantissa % 16) > 9) ? ((mantissa % 16) - 10 + a) - : ((mantissa % 16) + '0'); + char new_digit = + static_cast(((mantissa % 16) > 9) ? ((mantissa % 16) - 10 + a) + : ((mantissa % 16) + '0')); mant_buffer[mant_cur - 1] = new_digit; if (new_digit != '0' && first_non_zero < mant_cur) first_non_zero = mant_cur; diff --git a/libc/src/stdio/printf_core/float_inf_nan_converter.h b/libc/src/stdio/printf_core/float_inf_nan_converter.h --- a/libc/src/stdio/printf_core/float_inf_nan_converter.h +++ b/libc/src/stdio/printf_core/float_inf_nan_converter.h @@ -36,7 +36,8 @@ is_negative = float_bits.get_sign(); mantissa = float_bits.get_explicit_mantissa(); } else { - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; + fputil::FPBits::UIntType float_raw = + static_cast::UIntType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); is_negative = float_bits.get_sign(); mantissa = float_bits.get_explicit_mantissa(); diff --git a/libc/src/stdio/printf_core/int_converter.h b/libc/src/stdio/printf_core/int_converter.h --- a/libc/src/stdio/printf_core/int_converter.h +++ b/libc/src/stdio/printf_core/int_converter.h @@ -43,7 +43,7 @@ static constexpr size_t BITS_IN_BYTE = 8; static constexpr size_t BITS_IN_NUM = sizeof(uintmax_t) * BITS_IN_BYTE; - uintmax_t num = to_conv.conv_val_raw; + uintmax_t num = static_cast(to_conv.conv_val_raw); bool is_negative = false; FormatFlags flags = to_conv.flags;