67 static constexpr int bits{BITS};
68 static constexpr int partBits{PARTBITS};
70 using BigPart = BIGPART;
71 static_assert(std::is_integral_v<Part>);
72 static_assert(std::is_unsigned_v<Part>);
73 static_assert(std::is_integral_v<BigPart>);
74 static_assert(std::is_unsigned_v<BigPart>);
75 static_assert(CHAR_BIT *
sizeof(BigPart) >= 2 * partBits);
76 static constexpr bool littleEndian{IS_LITTLE_ENDIAN};
77 static constexpr int alignment{ALIGNMENT};
80 static constexpr int maxPartBits{CHAR_BIT *
sizeof(Part)};
81 static_assert(partBits > 0 && partBits <= maxPartBits);
82 static constexpr int extraPartBits{maxPartBits - partBits};
83 static constexpr int parts{(bits + partBits - 1) / partBits};
84 static_assert(parts >= 1);
85 static constexpr int extraTopPartBits{
86 extraPartBits + (parts * partBits) - bits};
87 static constexpr int topPartBits{maxPartBits - extraTopPartBits};
88 static_assert(topPartBits > 0 && topPartBits <= partBits);
89 static_assert((parts - 1) * partBits + topPartBits == bits);
90 static constexpr Part partMask{
static_cast<Part
>(~0) >> extraPartBits};
91 static constexpr Part topPartMask{
static_cast<Part
>(~0) >> extraTopPartBits};
92 static constexpr int partsWithAlignment{
93 (ALIGNMENT + partBits - 1) / partBits};
108 bool SignedMultiplicationOverflowed()
const {
109 return lower.IsNegative() ? (upper.POPCNT() != bits) : !upper.IsZero();
111 Integer upper, lower;
115 Integer quotient, remainder;
116 bool divisionByZero, overflow;
121 bool divisionByZero{
false}, overflow{
false}, zeroToZero{
false};
125 constexpr Integer() { Clear(); }
131 template <
typename INT,
typename = std::enable_if_t<std::is_
integral_v<INT>>>
133 constexpr int nBits = CHAR_BIT *
sizeof n;
134 if constexpr (nBits < partBits) {
135 if constexpr (std::is_unsigned_v<INT>) {
138 for (
int j{1}; j < parts; ++j) {
145 using SignedPart = std::make_signed_t<Part>;
146 Part p =
static_cast<SignedPart
>(n);
148 if constexpr (parts > 1) {
149 Part signExtension =
static_cast<SignedPart
>(-(n < 0));
150 for (
int j{1}; j < parts; ++j) {
151 SetLEPart(j, signExtension);
159 if constexpr (std::is_unsigned_v<INT>) {
160 for (
int j{0}; j < parts; ++j) {
161 SetLEPart(j,
static_cast<Part
>(n));
162 if constexpr (nBits > partBits) {
171 auto signExtension{std::make_unsigned_t<INT>(n < 0)};
172 signExtension = ~signExtension + 1;
173 static_assert(nBits >= partBits);
174 if constexpr (nBits > partBits) {
175 signExtension <<= nBits - partBits;
176 for (
int j{0}; j < parts; ++j) {
177 SetLEPart(j,
static_cast<Part
>(n));
182 SetLEPart(0,
static_cast<Part
>(n));
183 for (
int j{1}; j < parts; ++j) {
184 SetLEPart(j,
static_cast<Part
>(signExtension));
193 constexpr bool operator<(
const Integer &that)
const {
194 return CompareSigned(that) == Ordering::Less;
196 constexpr bool operator<=(
const Integer &that)
const {
197 return CompareSigned(that) != Ordering::Greater;
199 constexpr bool operator==(
const Integer &that)
const {
200 return CompareSigned(that) == Ordering::Equal;
202 constexpr bool operator!=(
const Integer &that)
const {
203 return !(*
this == that);
205 constexpr bool operator>=(
const Integer &that)
const {
206 return CompareSigned(that) != Ordering::Less;
208 constexpr bool operator>(
const Integer &that)
const {
209 return CompareSigned(that) == Ordering::Greater;
213 static constexpr Integer MASKL(
int places) {
216 }
else if (places >= bits) {
219 return MASKR(bits - places).NOT();
224 static constexpr Integer MASKR(
int places) {
227 for (; j + 1 < parts && places >= partBits; ++j, places -= partBits) {
228 result.LEPart(j) = partMask;
232 result.LEPart(j++) = partMask >> (partBits - places);
233 }
else if (j + 1 == parts) {
234 if (places >= topPartBits) {
235 result.LEPart(j++) = topPartMask;
237 result.LEPart(j++) = topPartMask >> (topPartBits - places);
241 for (; j < parts; ++j) {
242 result.LEPart(j) = 0;
247 static constexpr ValueWithOverflow Read(
248 const char *&pp, std::uint64_t base = 10,
bool isSigned =
false) {
250 bool overflow{
false};
252 while (*p ==
' ' || *p ==
'\t') {
255 bool negate{*p ==
'-'};
256 if (negate || *p ==
'+') {
257 while (*++p ==
' ' || *p ==
'\t') {
269 for (; std::uint64_t digit = *p; ++p) {
270 if (digit >=
'0' && digit <=
'9' && digit <
'0' + base) {
272 }
else if (base > 10 && digit >=
'A' && digit <
'A' + base - 10) {
274 }
else if (base > 10 && digit >=
'a' && digit <
'a' + base - 10) {
279 Product shifted{result.MultiplyUnsigned(radix)};
280 overflow |= !shifted.upper.IsZero();
281 ValueWithCarry next{shifted.lower.AddUnsigned(
Integer{digit})};
282 overflow |= next.carry;
287 result = result.Negate().value;
288 overflow |= isSigned && !result.IsNegative() && !result.IsZero();
290 overflow |= isSigned && result.IsNegative();
292 return {result, overflow};
295 template <
typename FROM>
296 static constexpr ValueWithOverflow ConvertUnsigned(
const FROM &that) {
297 std::uint64_t field{that.ToUInt64()};
298 ValueWithOverflow result{field,
false};
299 if constexpr (bits < 64) {
300 result.overflow = (field >> bits) != 0;
302 for (
int j{64}; j < that.bits && !result.overflow; j += 64) {
303 field = that.SHIFTR(j).ToUInt64();
305 result.overflow = field != 0;
307 result.value = result.value.IOR(
Integer{field}.SHIFTL(j));
309 result.overflow = (field >> (bits - j)) != 0;
316 template <
typename FROM>
317 static constexpr ValueWithOverflow ConvertSigned(
const FROM &that) {
318 ValueWithOverflow result{ConvertUnsigned(that)};
319 if constexpr (bits > FROM::bits) {
320 if (that.IsNegative()) {
321 result.value = result.value.IOR(MASKL(bits - FROM::bits));
323 result.overflow =
false;
324 }
else if constexpr (bits < FROM::bits) {
325 auto back{FROM::template ConvertSigned<Integer>(result.value)};
326 result.overflow = back.value.CompareUnsigned(that) != Ordering::Equal;
331 std::string UnsignedDecimal()
const {
332 if constexpr (bits < 4) {
333 char digit =
'0' + ToUInt64();
335 }
else if (IsZero()) {
338 QuotientWithRemainder qr{DivideUnsigned(10)};
339 char digit =
'0' + qr.remainder.ToUInt64();
340 if (qr.quotient.IsZero()) {
343 return qr.quotient.UnsignedDecimal() + digit;
348 std::string SignedDecimal()
const {
350 return std::string{
'-'} + Negate().value.UnsignedDecimal();
352 return UnsignedDecimal();
357 std::string Hexadecimal()
const {
359 int digits{(bits + 3) >> 2};
360 for (
int j{0}; j < digits; ++j) {
361 int pos{(digits - 1 - j) * 4};
362 char nybble = IBITS(pos, 4).ToUInt64();
363 if (nybble != 0 || !result.empty() || j + 1 == digits) {
364 char digit =
'0' + nybble;
366 digit +=
'a' - (
'9' + 1);
374 static constexpr int DIGITS{bits - 1};
375 static constexpr Integer HUGE() {
return MASKR(bits - 1); }
376 static constexpr Integer Least() {
return MASKL(1); }
377 static constexpr int RANGE{DecimalRange(bits - 1)};
378 static constexpr int UnsignedRANGE{DecimalRange(bits)};
380 constexpr bool IsZero()
const {
381 for (
int j{0}; j < parts; ++j) {
389 constexpr bool IsNegative()
const {
390 return (LEPart(parts - 1) >> (topPartBits - 1)) & 1;
393 constexpr Ordering CompareToZeroSigned()
const {
395 return Ordering::Less;
396 }
else if (IsZero()) {
397 return Ordering::Equal;
399 return Ordering::Greater;
405 constexpr int LEADZ()
const {
406 if (LEPart(parts - 1) != 0) {
407 int lzbc{common::LeadingZeroBitCount(LEPart(parts - 1))};
408 return lzbc - extraTopPartBits;
410 int upperZeroes{topPartBits};
411 for (
int j{1}; j < parts; ++j) {
412 if (Part p{LEPart(parts - 1 - j)}) {
413 int lzbc{common::LeadingZeroBitCount(p)};
414 return upperZeroes + lzbc - extraPartBits;
416 upperZeroes += partBits;
422 constexpr int POPCNT()
const {
424 for (
int j{0}; j < parts; ++j) {
425 count += common::BitPopulationCount(part_[j]);
431 constexpr bool POPPAR()
const {
return POPCNT() & 1; }
433 constexpr int TRAILZ()
const {
434 auto minus1{AddUnsigned(MASKR(bits))};
439 return IEOR(minus1.value).POPCNT() - 1;
443 constexpr bool BTEST(
int pos)
const {
444 if (pos < 0 || pos >= bits) {
447 return (LEPart(pos / partBits) >> (pos % partBits)) & 1;
451 constexpr Ordering CompareUnsigned(
const Integer &y)
const {
452 for (
int j{parts}; j-- > 0;) {
453 if (LEPart(j) > y.LEPart(j)) {
454 return Ordering::Greater;
456 if (LEPart(j) < y.LEPart(j)) {
457 return Ordering::Less;
460 return Ordering::Equal;
463 constexpr bool BGE(
const Integer &y)
const {
464 return CompareUnsigned(y) != Ordering::Less;
466 constexpr bool BGT(
const Integer &y)
const {
467 return CompareUnsigned(y) == Ordering::Greater;
469 constexpr bool BLE(
const Integer &y)
const {
return !BGT(y); }
470 constexpr bool BLT(
const Integer &y)
const {
return !BGE(y); }
472 constexpr Ordering CompareSigned(
const Integer &y)
const {
473 bool isNegative{IsNegative()};
474 if (isNegative != y.IsNegative()) {
475 return isNegative ? Ordering::Less : Ordering::Greater;
477 return CompareUnsigned(y);
480 template <
typename UINT = std::u
int64_t>
constexpr UINT ToUInt()
const {
482 std::size_t filled{partBits};
483 constexpr std::size_t maxBits{CHAR_BIT *
sizeof n};
484 for (
int j{1}; filled < maxBits && j < parts; ++j, filled += partBits) {
485 n |= UINT{LEPart(j)} << filled;
490 template <
typename SINT = std::
int64_t,
typename UINT = std::u
int64_t>
491 constexpr SINT ToSInt()
const {
494 SINT n{
static_cast<SINT
>(ToUInt<UINT>())};
495 constexpr std::size_t maxBits{CHAR_BIT *
sizeof n};
496 if constexpr (bits < maxBits) {
501 UINT u{ToUInt<UINT>()};
502 u = (u >> (bits - 1)) << (bits - 1);
504 n |=
static_cast<SINT
>(u);
509 constexpr std::uint64_t ToUInt64()
const {
return ToUInt<std::uint64_t>(); }
511 constexpr std::int64_t ToInt64()
const {
512 return ToSInt<std::int64_t, std::uint64_t>();
516 constexpr Integer NOT()
const {
518 for (
int j{0}; j < parts; ++j) {
519 result.SetLEPart(j, ~LEPart(j));
527 constexpr ValueWithOverflow Negate()
const {
530 for (
int j{0}; j + 1 < parts; ++j) {
531 Part newCarry{LEPart(j) == 0 && carry};
532 result.SetLEPart(j, ~LEPart(j) + carry);
535 Part top{LEPart(parts - 1)};
536 result.SetLEPart(parts - 1, ~top + carry);
537 bool overflow{top != 0 && result.LEPart(parts - 1) == top};
538 return {result, overflow};
541 constexpr ValueWithOverflow ABS()
const {
545 return {*
this,
false};
551 constexpr Integer ISHFT(
int count)
const {
553 return SHIFTR(-count);
555 return SHIFTL(count);
560 constexpr Integer SHIFTL(
int count)
const {
565 int shiftParts{count / partBits};
566 int bitShift{count - partBits * shiftParts};
569 for (; j >= shiftParts; --j) {
570 result.SetLEPart(j, LEPart(j - shiftParts));
572 for (; j >= 0; --j) {
573 result.LEPart(j) = 0;
576 for (; j > shiftParts; --j) {
578 ((LEPart(j - shiftParts) << bitShift) |
579 (LEPart(j - shiftParts - 1) >> (partBits - bitShift))));
581 if (j == shiftParts) {
582 result.SetLEPart(j, LEPart(0) << bitShift);
585 for (; j >= 0; --j) {
586 result.LEPart(j) = 0;
597 constexpr Integer ISHFTC(
int count,
int size = bits)
const {
598 if (count == 0 || size <= 0) {
608 int middleBits{size - count}, leastBits{count};
611 leastBits = size + count;
614 return SHIFTL(leastBits).IOR(SHIFTR(middleBits));
616 Integer unchanged{IAND(MASKL(bits - size))};
617 Integer middle{IAND(MASKR(middleBits)).SHIFTL(leastBits)};
618 Integer least{SHIFTR(middleBits).IAND(MASKR(leastBits))};
619 return unchanged.IOR(middle).IOR(least);
623 constexpr Integer SHIFTLWithFill(
const Integer &fill,
int count)
const {
626 }
else if (count >= 2 * bits) {
628 }
else if (count > bits) {
629 return fill.SHIFTL(count - bits);
630 }
else if (count == bits) {
633 return SHIFTL(count).IOR(fill.SHIFTR(bits - count));
637 constexpr Integer SHIFTRWithFill(
const Integer &fill,
int count)
const {
640 }
else if (count >= 2 * bits) {
642 }
else if (count > bits) {
643 return fill.SHIFTR(count - bits);
644 }
else if (count == bits) {
647 return SHIFTR(count).IOR(fill.SHIFTL(bits - count));
653 return SHIFTLWithFill(fill, count);
656 constexpr Integer DSHIFTR(
const Integer &value,
int count)
const {
658 return value.SHIFTRWithFill(*
this, count);
662 constexpr Integer SHIFTR(
int count)
const {
667 int shiftParts{count / partBits};
668 int bitShift{count - partBits * shiftParts};
671 for (; j + shiftParts < parts; ++j) {
672 result.LEPart(j) = LEPart(j + shiftParts);
674 for (; j < parts; ++j) {
675 result.LEPart(j) = 0;
678 for (; j + shiftParts + 1 < parts; ++j) {
680 (LEPart(j + shiftParts) >> bitShift) |
681 (LEPart(j + shiftParts + 1) << (partBits - bitShift)));
683 if (j + shiftParts + 1 == parts) {
684 result.LEPart(j++) = LEPart(parts - 1) >> bitShift;
686 for (; j < parts; ++j) {
687 result.LEPart(j) = 0;
696 constexpr Integer SHIFTA(
int count)
const {
699 }
else if (IsNegative()) {
700 return SHIFTR(count).IOR(MASKL(count));
702 return SHIFTR(count);
707 constexpr Integer IBCLR(
int pos)
const {
708 if (pos < 0 || pos >= bits) {
712 result.LEPart(pos / partBits) &= ~(Part{1} << (pos % partBits));
718 constexpr Integer IBSET(
int pos)
const {
719 if (pos < 0 || pos >= bits) {
723 result.LEPart(pos / partBits) |= Part{1} << (pos % partBits);
729 constexpr Integer IBITS(
int pos,
int size)
const {
730 return SHIFTR(pos).IAND(MASKR(size));
735 for (
int j{0}; j < parts; ++j) {
736 result.LEPart(j) = LEPart(j) & y.LEPart(j);
743 for (
int j{0}; j < parts; ++j) {
744 result.LEPart(j) = LEPart(j) | y.LEPart(j);
751 for (
int j{0}; j < parts; ++j) {
752 result.LEPart(j) = LEPart(j) ^ y.LEPart(j);
758 return IAND(mask).IOR(y.IAND(mask.NOT()));
762 if (CompareSigned(y) == Ordering::Less) {
770 if (CompareSigned(y) == Ordering::Less) {
778 constexpr ValueWithCarry AddUnsigned(
779 const Integer &y,
bool carryIn =
false)
const {
781 BigPart carry{carryIn};
782 for (
int j{0}; j + 1 < parts; ++j) {
784 carry += y.LEPart(j);
785 sum.SetLEPart(j, carry);
788 carry += LEPart(parts - 1);
789 carry += y.LEPart(parts - 1);
790 sum.SetLEPart(parts - 1, carry);
791 return {sum, carry > topPartMask};
794 constexpr ValueWithOverflow AddSigned(
const Integer &y)
const {
795 bool isNegative{IsNegative()};
796 bool sameSign{isNegative == y.IsNegative()};
797 ValueWithCarry sum{AddUnsigned(y)};
798 bool overflow{sameSign && sum.value.IsNegative() != isNegative};
799 return {sum.value, overflow};
802 constexpr ValueWithOverflow SubtractSigned(
const Integer &y)
const {
803 bool isNegative{IsNegative()};
804 bool sameSign{isNegative == y.IsNegative()};
805 ValueWithCarry diff{AddUnsigned(y.Negate().value)};
806 bool overflow{!sameSign && diff.value.IsNegative() != isNegative};
807 return {diff.value, overflow};
811 constexpr ValueWithOverflow DIM(
const Integer &y)
const {
812 if (CompareSigned(y) != Ordering::Greater) {
815 return SubtractSigned(y);
819 constexpr ValueWithOverflow SIGN(
bool toNegative)
const {
820 if (toNegative == IsNegative()) {
821 return {*
this,
false};
822 }
else if (toNegative) {
829 constexpr ValueWithOverflow SIGN(
const Integer &sign)
const {
830 return SIGN(sign.IsNegative());
833 constexpr Product MultiplyUnsigned(
const Integer &y)
const {
834 Part product[2 * parts]{};
835 for (
int j{0}; j < parts; ++j) {
836 if (Part xpart{LEPart(j)}) {
837 for (
int k{0}; k < parts; ++k) {
838 if (Part ypart{y.LEPart(k)}) {
841#if defined __GNUC__ && __GNUC__ < 8 || __GNUC__ >= 12
844 for (
int to{j + k}; xy != 0 && to < (2 * parts); ++to) {
846 for (
int to{j + k}; xy != 0; ++to) {
849 product[to] = xy & partMask;
856 Integer upper{
nullptr}, lower{
nullptr};
857 for (
int j{0}; j < parts; ++j) {
858 lower.LEPart(j) = product[j];
859 upper.LEPart(j) = product[j + parts];
861 if constexpr (topPartBits < partBits) {
862 upper = upper.SHIFTL(partBits - topPartBits);
863 upper.LEPart(0) |= lower.LEPart(parts - 1) >> topPartBits;
864 lower.LEPart(parts - 1) &= topPartMask;
866 return {upper, lower};
869 constexpr Product MultiplySigned(
const Integer &y)
const {
870 bool yIsNegative{y.IsNegative()};
873 absy = y.Negate().value;
875 bool isNegative{IsNegative()};
878 absx = Negate().value;
880 Product product{absx.MultiplyUnsigned(absy)};
881 if (isNegative != yIsNegative) {
882 product.lower = product.lower.NOT();
883 product.upper = product.upper.NOT();
885 auto incremented{product.lower.AddUnsigned(one)};
886 product.lower = incremented.value;
887 if (incremented.carry) {
888 product.upper = product.upper.AddUnsigned(one).value;
894 constexpr QuotientWithRemainder DivideUnsigned(
const Integer &divisor)
const {
895 if (divisor.IsZero()) {
896 return {MASKR(bits),
Integer{},
true,
false};
898 int bitsDone{LEADZ()};
901 for (; bitsDone < bits; ++bitsDone) {
902 auto doubledTop{top.AddUnsigned(top)};
903 top = doubledTop.value;
904 remainder = remainder.AddUnsigned(remainder, doubledTop.carry).value;
905 bool nextBit{remainder.CompareUnsigned(divisor) != Ordering::Less};
906 quotient = quotient.AddUnsigned(quotient, nextBit).value;
908 remainder = remainder.SubtractSigned(divisor).value;
911 return {quotient, remainder,
false,
false};
917 constexpr QuotientWithRemainder DivideSigned(
Integer divisor)
const {
918 bool dividendIsNegative{IsNegative()};
919 bool negateQuotient{dividendIsNegative};
920 Ordering divisorOrdering{divisor.CompareToZeroSigned()};
921 if (divisorOrdering == Ordering::Less) {
922 negateQuotient = !negateQuotient;
923 auto negated{divisor.Negate()};
924 if (negated.overflow) {
926 if (CompareUnsigned(divisor) == Ordering::Equal) {
927 return {MASKR(1),
Integer{},
false, bits <= 1};
929 return {
Integer{}, *
this,
false,
false};
932 divisor = negated.value;
933 }
else if (divisorOrdering == Ordering::Equal) {
935 if (dividendIsNegative) {
936 return {MASKL(1),
Integer{},
true,
false};
938 return {MASKR(bits - 1),
Integer{},
true,
false};
942 if (dividendIsNegative) {
943 auto negated{Negate()};
944 if (negated.overflow) {
947 if (divisorOrdering == Ordering::Less &&
948 divisor.CompareUnsigned(
Integer{1}) == Ordering::Equal) {
950 return {*
this,
Integer{},
false,
true};
953 dividend = negated.value;
958 QuotientWithRemainder result{dividend.DivideUnsigned(divisor)};
959 if (negateQuotient) {
960 result.quotient = result.quotient.Negate().value;
962 if (dividendIsNegative) {
963 result.remainder = result.remainder.Negate().value;
970 constexpr ValueWithOverflow MODULO(
const Integer &divisor)
const {
971 bool negativeDivisor{divisor.IsNegative()};
972 bool distinctSigns{IsNegative() != negativeDivisor};
973 QuotientWithRemainder divided{DivideSigned(divisor)};
974 if (distinctSigns && !divided.remainder.IsZero()) {
975 return {divided.remainder.AddUnsigned(divisor).value, divided.overflow};
977 return {divided.remainder, divided.overflow};
981 constexpr PowerWithErrors Power(
const Integer &exponent)
const {
982 PowerWithErrors result{1,
false,
false,
false};
983 if (exponent.IsZero()) {
990 result.zeroToZero = IsZero();
991 }
else if (exponent.IsNegative()) {
993 result.divisionByZero =
true;
994 result.power = MASKR(bits - 1);
995 }
else if (CompareSigned(
Integer{1}) == Ordering::Equal) {
996 result.power = *
this;
997 }
else if (CompareSigned(
Integer{-1}) == Ordering::Equal) {
998 if (exponent.BTEST(0)) {
999 result.power = *
this;
1002 result.power.Clear();
1007 int nbits{bits - pow.LEADZ()};
1008 for (
int j{0}; j < nbits; ++j) {
1010 Product product{result.power.MultiplySigned(shifted)};
1011 result.power = product.lower;
1012 result.overflow |= product.SignedMultiplicationOverflowed();
1014 if (j + 1 < nbits) {
1015 Product squared{shifted.MultiplySigned(shifted)};
1016 result.overflow |= squared.SignedMultiplicationOverflowed();
1017 shifted = squared.lower;
1025 static constexpr std::size_t
bytesStored() {
return sizeof(Integer{}); }
1030 const void *raw, [[maybe_unused]] std::size_t expectedSize) {
1041 bool *changed =
nullptr)
const {
1056 constexpr Integer(std::nullptr_t) {}
1059 constexpr const Part &LEPart(
int part)
const {
1060 if constexpr (littleEndian) {
1063 return part_[parts - 1 - part];
1067 constexpr Part &LEPart(
int part) {
1068 if constexpr (littleEndian) {
1071 return part_[parts - 1 - part];
1075 constexpr void SetLEPart(
int part, Part x) {
1076 LEPart(part) = x & PartMask(part);
1079 static constexpr Part PartMask(
int part) {
1080 return part == parts - 1 ? topPartMask : partMask;
1083 constexpr void Clear() {
1084 for (
int j{0}; j < parts; ++j) {
1089 Part part_[partsWithAlignment]{};