28 }
else if (x > std::numeric_limits<int64_t>::min()) {
42 return (Abs256(x.first) << 32) + Abs256(x.second);
45 return (Abs256(x.first) << 32) - Abs256(x.second);
49 std::strong_ordering MulCompare(int64_t a1, int64_t a2, int64_t b1, int64_t b2)
52 int sign_a = (a1 == 0 ? 0 : a1 < 0 ? -1 : 1) * (a2 == 0 ? 0 : a2 < 0 ? -1 : 1);
53 int sign_b = (b1 == 0 ? 0 : b1 < 0 ? -1 : 1) * (b2 == 0 ? 0 : b2 < 0 ? -1 : 1);
54 if (sign_a != sign_b)
return sign_a <=> sign_b;
57 auto mul_abs_a = Abs256(a1) * Abs256(a2), mul_abs_b = Abs256(b1) * Abs256(b2);
61 return mul_abs_b <=> mul_abs_a;
63 return mul_abs_a <=> mul_abs_b;
74 int32_t s1 = provider.ConsumeIntegral<int32_t>();
79 int64_t f2 = provider.ConsumeIntegral<int64_t>();
80 int32_t s2 = provider.ConsumeIntegral<int32_t>();
86 auto cmp_feerate = MulCompare(f1, s2, f2, s1);
87 assert(FeeRateCompare(fr1, fr2) == cmp_feerate);
88 assert((fr1 << fr2) == std::is_lt(cmp_feerate));
89 assert((fr1 >> fr2) == std::is_gt(cmp_feerate));
93 assert(cmp_mul == cmp_feerate);
97 assert(cmp_fallback == cmp_feerate);
100 auto cmp_total = std::is_eq(cmp_feerate) ? (s2 <=> s1) : cmp_feerate;
101 assert((fr1 <=> fr2) == cmp_total);
102 assert((fr1 < fr2) == std::is_lt(cmp_total));
103 assert((fr1 > fr2) == std::is_gt(cmp_total));
104 assert((fr1 <= fr2) == std::is_lteq(cmp_total));
105 assert((fr1 >= fr2) == std::is_gteq(cmp_total));
106 assert((fr1 == fr2) == std::is_eq(cmp_total));
107 assert((fr1 != fr2) == std::is_neq(cmp_total));
117 auto num_low = provider.ConsumeIntegral<uint32_t>();
118 std::pair<int64_t, uint32_t> num{num_high, num_low};
119 auto den = provider.ConsumeIntegralInRange<int32_t>(1, std::numeric_limits<int32_t>::max());
120 auto round_down = provider.ConsumeBool();
123 bool is_negative = num_high < 0;
127 auto num_abs = Abs256(num);
128 auto den_abs = Abs256(den);
129 auto quot_abs = (is_negative == round_down) ?
130 (num_abs + den_abs - 1) / den_abs :
134 if ((is_negative && quot_abs > MAX_ABS_INT64) || (!is_negative && quot_abs >= MAX_ABS_INT64)) {
140 assert(res == 0 || (res < 0) == is_negative);
141 assert(Abs256(res) == quot_abs);
144 long double expect = round_down ? std::floor(num_high * 4294967296.0L + num_low) / den
145 : std::ceil(num_high * 4294967296.0L + num_low) / den;
148 assert(res >= -1 && res <= 1);
149 }
else if (
expect > 0.0L) {
169 auto mul64 = provider.ConsumeIntegral<int64_t>();
170 auto div = provider.ConsumeIntegralInRange<int32_t>(1, std::numeric_limits<int32_t>::max());
171 auto round_down = provider.ConsumeBool();
174 bool is_negative = ((mul32 < 0) && (mul64 > 0)) || ((mul32 > 0) && (mul64 < 0));
178 auto prod_abs = Abs256(mul32) * Abs256(mul64);
179 auto div_abs = Abs256(div);
180 auto quot_abs = (is_negative == round_down) ?
181 (prod_abs + div_abs - 1) / div_abs :
185 if ((is_negative && quot_abs > MAX_ABS_INT64) || (!is_negative && quot_abs >= MAX_ABS_INT64)) {
188 assert(mul32 < 0 || mul32 > div);
194 assert(res == 0 || (res < 0) == is_negative);
195 assert(Abs256(res) == quot_abs);
199 assert(res == res_fallback);
202 long double expect = round_down ? std::floor(static_cast<long double>(mul32) * mul64 / div)
203 : std::ceil(static_cast<long double>(mul32) * mul64 / div);
206 assert(res >= -1 && res <= 1);
207 }
else if (
expect > 0.0L) {
217 auto res_fee = round_down ?
223 if (mul64 < std::numeric_limits<int64_t>::max() / 1000 &&
224 mul64 > std::numeric_limits<int64_t>::min() / 1000 &&
225 quot_abs <
arith_uint256{std::numeric_limits<int64_t>::max() / 1000}) {
228 auto allowed_gap =
static_cast<int64_t
>(mul32 / 1000 + 3 + round_down);
229 assert(feerate_fee - res_fee >= -allowed_gap);
230 assert(feerate_fee - res_fee <= allowed_gap);
static int64_t DivFallback(std::pair< int64_t, uint32_t > n, int32_t d, bool round_down) noexcept
Helper function for 96/32 signed division, rounding towards negative infinity (if round_down) or posi...
int64_t CAmount
Amount in satoshis (Can be negative)
int64_t EvaluateFeeUp(int32_t at_size) const noexcept
Compute the fee for a given size at_size using this object's feerate, rounding up.
static constexpr auto Div
bool IsEmpty() const noexcept
Check if this is empty (size and fee are 0).
256-bit unsigned big integer.
static std::pair< int64_t, uint32_t > MulFallback(int64_t a, int32_t b) noexcept
Helper function for 32*64 signed multiplication, returning an unspecified but totally ordered type...
static constexpr auto Mul
Data structure storing a fee and size, ordered by increasing fee/size.
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac...
CAmount GetFee(int32_t virtual_bytes) const
Return the fee in satoshis for the given vsize in vbytes.
int64_t EvaluateFeeDown(int32_t at_size) const noexcept
Compute the fee for a given size at_size using this object's feerate, rounding down.