1#ifndef NEFORCE_CORE_CONFIG_MSVC_INTRINSIC_HPP__
2#define NEFORCE_CORE_CONFIG_MSVC_INTRINSIC_HPP__
18NEFORCE_BEGIN_NAMESPACE__
38 const auto a_lo =
static_cast<uint32_t>(a);
39 const auto a_hi =
static_cast<uint32_t>(a >> 32);
40 const auto b_lo =
static_cast<uint32_t>(b);
41 const auto b_hi =
static_cast<uint32_t>(b >> 32);
46 *out = (sum_hi << 32) | (sum_lo & 0xFFFFFFFFULL);
47 return static_cast<uint8_t>(sum_hi >> 32);
62 const auto a_lo =
static_cast<uint32_t>(a);
63 const auto a_hi =
static_cast<uint32_t>(a >> 32);
64 const auto b_lo =
static_cast<uint32_t>(b);
65 const auto b_hi =
static_cast<uint32_t>(b >> 32);
68 const uint64_t borrow_lo = (diff_lo >> 63);
71 const uint64_t borrow_hi = (diff_hi >> 63);
73 *out = ((diff_hi & 0xFFFFFFFFULL) << 32) | (diff_lo & 0xFFFFFFFFULL);
74 return static_cast<uint8_t>(borrow_hi);
87 const auto a_lo =
static_cast<uint32_t>(a);
88 const auto a_hi =
static_cast<uint32_t>(a >> 32);
89 const auto b_lo =
static_cast<uint32_t>(b);
90 const auto b_hi =
static_cast<uint32_t>(b >> 32);
97 const uint64_t mid = (p_ll >> 32) + (p_lh & 0xFFFFFFFFULL) + (p_hl & 0xFFFFFFFFULL);
98 const uint64_t lo = (p_ll & 0xFFFFFFFFULL) | (mid << 32);
99 const uint64_t hi = p_hh + (p_lh >> 32) + (p_hl >> 32) + (mid >> 32);
115 if (dividend_hi == 0) {
119 return dividend_lo / divisor;
122 const int s = _NEFORCE
clz64(divisor);
130 u2 = dividend_hi >> (64 - s);
131 u1 = (dividend_hi << s) | (dividend_lo >> (64 - s));
132 u0 = dividend_lo << s;
135 const auto d_hi =
static_cast<uint32_t>(d >> 32);
136 const auto d_lo =
static_cast<uint32_t>(d);
142 while (q1 >= 0x100000000ULL || q1 * d_lo > ((r1 << 32) | (u1 & 0xFFFFFFFF))) {
145 if (r1 >= 0x100000000ULL) {
158 if ((rem_hi & (1ULL << 63)) != 0U) {
170 while (q0 >= 0x100000000ULL || q0 * d_lo > ((r0 << 32) | (rem_lo & 0xFFFFFFFF))) {
173 if (r0 >= 0x100000000ULL) {
178 prod_lo = _NEFORCE
_umul128(q0, d, &prod_hi);
180 uint64_t rem_mid_lo = rem_lo - prod_lo;
181 if (rem_lo < prod_lo) {
185 if ((rem_mid_hi & (1ULL << 63)) != 0U) {
190 const uint64_t quotient = (q1 << 32) | q0;
194 *
remainder = (rem_mid_lo << (64 - s)) | (u0 >> s);
205NEFORCE_END_NAMESPACE__
constexpr int clz64(uint64_t x) noexcept
计算64位整数前导零的个数
unsigned char uint8_t
8位无符号整数类型
unsigned int uint32_t
32位无符号整数类型
unsigned long long uint64_t
64位无符号整数类型
constexpr uint64_t _umul128(const uint64_t a, const uint64_t b, uint64_t *hi_out) noexcept
64位无符号乘法
constexpr uint8_t _subborrow_u64(const uint8_t borrow_in, const uint64_t a, const uint64_t b, uint64_t *out) noexcept
带借位的64位无符号减法
constexpr uint64_t _udiv128(const uint64_t dividend_hi, const uint64_t dividend_lo, const uint64_t divisor, uint64_t *remainder) noexcept
128位无符号除法(基于Knuth-D)
constexpr uint8_t _addcarry_u64(const uint8_t carry_in, const uint64_t a, const uint64_t b, uint64_t *out) noexcept
带进位的64位无符号加法
constexpr decimal_t remainder(const decimal_t x, const decimal_t y) noexcept
计算余数