27template<
typename T,
int S>
struct UIntF {
28 static_assert(std::is_unsigned_v<T>);
29 static_assert(S >= 1);
50 explicit operator double()
const;
51 explicit operator float()
const;
59 std::string
to_string(
int base = 10)
const;
66template<
typename T,
int S>
struct IntF {
67 static_assert(std::is_unsigned_v<T>);
68 static_assert(S >= 1);
92 explicit operator double()
const;
93 explicit operator float()
const;
104 std::string
to_string(
int base = 10)
const;
171 constexpr int Count = std::min(S,
int(
sizeof(
decltype(value)) /
sizeof(
T)));
172 constexpr int BitsPerT = 8 *
sizeof(
T);
174 for (
int i = 0;
i < Count;
i++) {
175 this->
v[
i] =
T(value >> (BitsPerT *
i));
177 for (
int i = Count;
i < S;
i++) {
184 constexpr int Count = std::min(S,
int(
sizeof(
decltype(value)) /
sizeof(
T)));
185 constexpr int BitsPerT = 8 *
sizeof(
T);
187 for (
int i = 0;
i < Count;
i++) {
188 this->
v[
i] =
T(value >> (BitsPerT *
i));
190 const T sign_extend_fill = value < 0 ?
T(-1) :
T(0);
191 for (
int i = Count;
i < S;
i++) {
192 this->
v[
i] = sign_extend_fill;
201 this->set_from_str(
str, base);
206 this->set_from_str(
str, base);
212 constexpr int Count = std::min(S,
int(
sizeof(
uint64_t) /
sizeof(
T)));
213 constexpr int BitsPerT = 8 *
sizeof(
T);
216 for (
int i = 0;
i < Count;
i++) {
224 double result = double(this->
v[0]);
225 for (
int i = 1;
i < S;
i++) {
226 const T a = this->
v[
i];
237 return float(
double(*
this));
248 return -double(-*
this);
250 double result = double(this->
v[0]);
251 for (
int i = 1;
i < S;
i++) {
252 const T a = this->
v[
i];
263 return float(
double(*
this));
284template<
typename T,
typename T2,
int S>
287 constexpr int shift = 8 *
sizeof(
T);
290 const T2 ai =
T2(a[
i]);
292 const T2 ri = ai + bi + carry;
301template<
typename T,
typename T2,
int S>
306 const T2 ai =
T2(a[
i]);
308 const T2 ri = ai - bi - carry;
315template<
typename T,
typename T2,
int S>
318 constexpr int shift = 8 *
sizeof(
T);
322 for (
int i = 0;
i < S;
i++) {
325 for (
int j = 0; j < S -
i; j++) {
326 const T2 rji =
T2(a[j]) * bi + carry;
327 carry = rji >> shift;
328 r[
i + j] +=
T2(
T(rji));
333 for (
int i = 0;
i < S;
i++) {
334 const T2 ri = r[
i] + carry;
340template<
typename T,
int Size, BLI_ENABLE_IF((!std::is_
void_v<
double_u
int_type<T>>))>
348template<
typename T,
int Size, BLI_ENABLE_IF((!std::is_
void_v<
double_u
int_type<T>>))>
356template<
typename T,
int Size>
364template<
typename T,
int Size>
372template<
typename T,
int Size, BLI_ENABLE_IF((!std::is_
void_v<
double_u
int_type<T>>))>
386 return (a.
v[Size - 1] & (
T(1) << (
sizeof(
T) * 8 - 1))) != 0;
403template<
typename T,
int Size, BLI_ENABLE_IF((!std::is_
void_v<
double_u
int_type<T>>))>
412 if (is_negative_a && is_negative_b) {
427 for (
int i = 0;
i < Size;
i++) {
463template<
typename T,
int Size>
469template<
typename T,
int Size>
475template<
typename T,
int Size>
481template<
typename T,
int Size>
487template<
typename T,
size_t Size>
490 for (
int i = Size - 1;
i >= 0;
i--) {
501template<
typename T,
int Size>
506 if (is_negative_a == is_negative_b) {
509 return is_negative_a;
512template<
typename T,
int Size>
517 if (is_negative_a == is_negative_b) {
520 return is_negative_a;
523template<
typename T,
int Size>
528 if (is_negative_a == is_negative_b) {
531 return is_negative_b;
534template<
typename T,
int Size>
539 if (is_negative_a == is_negative_b) {
542 return is_negative_b;
545template<
typename T,
int Size>
551template<
typename T,
int Size>
557template<
typename T,
int Size>
563template<
typename T,
int Size>
unsigned long long int uint64_t
static const char * to_string(const Interpolation &interp)
void operator*=(UIntF< T, Size > &a, const UIntF< T, Size > &b)
UIntF< T, Size > operator*(const UIntF< T, Size > &a, const UIntF< T, Size > &b)
bool is_zero(const UIntF< T, Size > &a)
void operator+=(UIntF< T, Size > &a, const UIntF< T, Size > &b)
IntF< uint8_t, 8 > Int64_8
IntF< uint32_t, 2 > Int64_32
bool operator!=(const IntF< T, Size > &a, const IntF< T, Size > &b)
UIntF< T, Size > operator-(const UIntF< T, Size > &a, const UIntF< T, Size > &b)
IntF< uint8_t, 32 > Int256_8
IntF< uint16_t, 4 > Int64_16
IntF< uint64_t, 4 > Int256_64
UIntF< uint32_t, 4 > UInt128_32
IntF< uint32_t, 8 > Int256_32
IntF< uint16_t, 16 > Int256_16
UIntF< T, Size > operator+(const UIntF< T, Size > &a, const UIntF< T, Size > &b)
int compare_reversed_order(const std::array< T, Size > &a, const std::array< T, Size > &b)
UIntF< uint16_t, 16 > UInt256_16
UIntF< uint32_t, 2 > UInt64_32
IntF< uint32_t, 4 > Int128_32
UIntF< uint16_t, 8 > UInt128_16
UIntF< uint8_t, 8 > UInt64_8
bool operator==(const IntF< T, Size > &a, const IntF< T, Size > &b)
bool operator>(const IntF< T, Size > &a, const IntF< T, Size > &b)
void generic_unsigned_mul(T *__restrict dst, const T *a, const T *b)
UIntF< uint8_t, 16 > UInt128_8
IntF< uint16_t, 8 > Int128_16
UIntF< uint16_t, 4 > UInt64_16
UIntF< uint32_t, 8 > UInt256_32
IntF< uint8_t, 16 > Int128_8
IntF< uint64_t, 2 > Int128_64
typename DoubleUIntType< T >::type double_uint_type
bool operator>=(const IntF< T, Size > &a, const IntF< T, Size > &b)
void generic_add(T *__restrict dst, const T *a, const T *b)
void generic_sub(T *__restrict dst, const T *a, const T *b)
UIntF< uint64_t, 4 > UInt256_64
UIntF< uint64_t, 2 > UInt128_64
bool operator<(const IntF< T, Size > &a, const IntF< T, Size > &b)
bool operator<=(const IntF< T, Size > &a, const IntF< T, Size > &b)
UIntF< uint8_t, 32 > UInt256_8
bool is_negative(const IntF< T, Size > &a)
void operator-=(UIntF< T, Size > &a, const UIntF< T, Size > &b)
IntF(const UIntF< T, S > &value)
IntF(StringRefNull str, int base=10)
std::array< uint8_t, S > v
std::array< uint8_t, S > v
UIntF(StringRefNull str, int base=10)