7 #if !defined(CNL_IMPL_CHARCONV_DESCALE_H)
8 #define CNL_IMPL_CHARCONV_DESCALE_H
10 #include "../../integer.h"
11 #include "../cstdint/types.h"
12 #include "../numbers/signedness.h"
13 #include "../scaled/declaration.h"
14 #include "../unreachable.h"
19 namespace cnl::_impl {
20 template<
integer Rep,
int Radix>
24 static constexpr
int radix = Radix;
30 int InExponent = 0,
int InRadix = 2,
32 [[nodiscard]] constexpr
auto descale(Rep
const& input, power<InExponent, InRadix>)
34 descaled<Significand, OutRadix> output{
static_cast<Significand
>(input), 0};
42 ? []([[maybe_unused]] Significand
const& n) ->
bool {
43 if constexpr (numbers::signedness_v<Significand>) {
46 return unreachable<bool>(
"negative unsigned integer");
49 : [](Significand
const& n) {
53 if constexpr (InExponent < 0) {
54 for (
int in_exponent = InExponent;
55 in_exponent != 0 || (Precise && !(output.significand % OutRadix));) {
56 if (output.significand % InRadix) {
57 if (oob(output.significand)) {
59 unreachable<descaled<Significand, OutRadix>>(
"number cannot be represented in this form");
62 output.significand *= OutRadix;
68 output.significand /= InRadix;
72 for (
int in_exponent = InExponent;
73 in_exponent != 0 || !(output.significand % OutRadix);) {
74 if (!(output.significand % OutRadix)) {
75 output.significand /= OutRadix;
80 if (!oob(output.significand)) {
81 output.significand *= InRadix;
91 #endif // CNL_IMPL_CHARCONV_DESCALE_H