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 {
492 SINT n = ToUInt<UINT>();
493 constexpr std::size_t maxBits{CHAR_BIT *
sizeof n};
494 if constexpr (bits < maxBits) {
497 auto u{std::make_unsigned_t<SINT>(ToUInt())};
498 u = (u >> (bits - 1)) << (bits - 1);
500 n |=
static_cast<SINT
>(u);
505 constexpr std::uint64_t ToUInt64()
const {
return ToUInt<std::uint64_t>(); }
507 constexpr std::int64_t ToInt64()
const {
508 return ToSInt<std::int64_t, std::uint64_t>();
512 constexpr Integer NOT()
const {
514 for (
int j{0}; j < parts; ++j) {
515 result.SetLEPart(j, ~LEPart(j));
523 constexpr ValueWithOverflow Negate()
const {
526 for (
int j{0}; j + 1 < parts; ++j) {
527 Part newCarry{LEPart(j) == 0 && carry};
528 result.SetLEPart(j, ~LEPart(j) + carry);
531 Part top{LEPart(parts - 1)};
532 result.SetLEPart(parts - 1, ~top + carry);
533 bool overflow{top != 0 && result.LEPart(parts - 1) == top};
534 return {result, overflow};
537 constexpr ValueWithOverflow ABS()
const {
541 return {*
this,
false};
547 constexpr Integer ISHFT(
int count)
const {
549 return SHIFTR(-count);
551 return SHIFTL(count);
556 constexpr Integer SHIFTL(
int count)
const {
561 int shiftParts{count / partBits};
562 int bitShift{count - partBits * shiftParts};
565 for (; j >= shiftParts; --j) {
566 result.SetLEPart(j, LEPart(j - shiftParts));
568 for (; j >= 0; --j) {
569 result.LEPart(j) = 0;
572 for (; j > shiftParts; --j) {
574 ((LEPart(j - shiftParts) << bitShift) |
575 (LEPart(j - shiftParts - 1) >> (partBits - bitShift))));
577 if (j == shiftParts) {
578 result.SetLEPart(j, LEPart(0) << bitShift);
581 for (; j >= 0; --j) {
582 result.LEPart(j) = 0;
593 constexpr Integer ISHFTC(
int count,
int size = bits)
const {
594 if (count == 0 || size <= 0) {
604 int middleBits{size - count}, leastBits{count};
607 leastBits = size + count;
610 return SHIFTL(leastBits).IOR(SHIFTR(middleBits));
612 Integer unchanged{IAND(MASKL(bits - size))};
613 Integer middle{IAND(MASKR(middleBits)).SHIFTL(leastBits)};
614 Integer least{SHIFTR(middleBits).IAND(MASKR(leastBits))};
615 return unchanged.IOR(middle).IOR(least);
619 constexpr Integer SHIFTLWithFill(
const Integer &fill,
int count)
const {
622 }
else if (count >= 2 * bits) {
624 }
else if (count > bits) {
625 return fill.SHIFTL(count - bits);
626 }
else if (count == bits) {
629 return SHIFTL(count).IOR(fill.SHIFTR(bits - count));
633 constexpr Integer SHIFTRWithFill(
const Integer &fill,
int count)
const {
636 }
else if (count >= 2 * bits) {
638 }
else if (count > bits) {
639 return fill.SHIFTR(count - bits);
640 }
else if (count == bits) {
643 return SHIFTR(count).IOR(fill.SHIFTL(bits - count));
649 return SHIFTLWithFill(fill, count);
652 constexpr Integer DSHIFTR(
const Integer &value,
int count)
const {
654 return value.SHIFTRWithFill(*
this, count);
658 constexpr Integer SHIFTR(
int count)
const {
663 int shiftParts{count / partBits};
664 int bitShift{count - partBits * shiftParts};
667 for (; j + shiftParts < parts; ++j) {
668 result.LEPart(j) = LEPart(j + shiftParts);
670 for (; j < parts; ++j) {
671 result.LEPart(j) = 0;
674 for (; j + shiftParts + 1 < parts; ++j) {
676 (LEPart(j + shiftParts) >> bitShift) |
677 (LEPart(j + shiftParts + 1) << (partBits - bitShift)));
679 if (j + shiftParts + 1 == parts) {
680 result.LEPart(j++) = LEPart(parts - 1) >> bitShift;
682 for (; j < parts; ++j) {
683 result.LEPart(j) = 0;
692 constexpr Integer SHIFTA(
int count)
const {
695 }
else if (IsNegative()) {
696 return SHIFTR(count).IOR(MASKL(count));
698 return SHIFTR(count);
703 constexpr Integer IBCLR(
int pos)
const {
704 if (pos < 0 || pos >= bits) {
708 result.LEPart(pos / partBits) &= ~(Part{1} << (pos % partBits));
714 constexpr Integer IBSET(
int pos)
const {
715 if (pos < 0 || pos >= bits) {
719 result.LEPart(pos / partBits) |= Part{1} << (pos % partBits);
725 constexpr Integer IBITS(
int pos,
int size)
const {
726 return SHIFTR(pos).IAND(MASKR(size));
731 for (
int j{0}; j < parts; ++j) {
732 result.LEPart(j) = LEPart(j) & y.LEPart(j);
739 for (
int j{0}; j < parts; ++j) {
740 result.LEPart(j) = LEPart(j) | y.LEPart(j);
747 for (
int j{0}; j < parts; ++j) {
748 result.LEPart(j) = LEPart(j) ^ y.LEPart(j);
754 return IAND(mask).IOR(y.IAND(mask.NOT()));
758 if (CompareSigned(y) == Ordering::Less) {
766 if (CompareSigned(y) == Ordering::Less) {
774 constexpr ValueWithCarry AddUnsigned(
775 const Integer &y,
bool carryIn =
false)
const {
777 BigPart carry{carryIn};
778 for (
int j{0}; j + 1 < parts; ++j) {
780 carry += y.LEPart(j);
781 sum.SetLEPart(j, carry);
784 carry += LEPart(parts - 1);
785 carry += y.LEPart(parts - 1);
786 sum.SetLEPart(parts - 1, carry);
787 return {sum, carry > topPartMask};
790 constexpr ValueWithOverflow AddSigned(
const Integer &y)
const {
791 bool isNegative{IsNegative()};
792 bool sameSign{isNegative == y.IsNegative()};
793 ValueWithCarry sum{AddUnsigned(y)};
794 bool overflow{sameSign && sum.value.IsNegative() != isNegative};
795 return {sum.value, overflow};
798 constexpr ValueWithOverflow SubtractSigned(
const Integer &y)
const {
799 bool isNegative{IsNegative()};
800 bool sameSign{isNegative == y.IsNegative()};
801 ValueWithCarry diff{AddUnsigned(y.Negate().value)};
802 bool overflow{!sameSign && diff.value.IsNegative() != isNegative};
803 return {diff.value, overflow};
807 constexpr ValueWithOverflow DIM(
const Integer &y)
const {
808 if (CompareSigned(y) != Ordering::Greater) {
811 return SubtractSigned(y);
815 constexpr ValueWithOverflow SIGN(
bool toNegative)
const {
816 if (toNegative == IsNegative()) {
817 return {*
this,
false};
818 }
else if (toNegative) {
825 constexpr ValueWithOverflow SIGN(
const Integer &sign)
const {
826 return SIGN(sign.IsNegative());
829 constexpr Product MultiplyUnsigned(
const Integer &y)
const {
830 Part product[2 * parts]{};
831 for (
int j{0}; j < parts; ++j) {
832 if (Part xpart{LEPart(j)}) {
833 for (
int k{0}; k < parts; ++k) {
834 if (Part ypart{y.LEPart(k)}) {
837#if defined __GNUC__ && __GNUC__ < 8 || __GNUC__ >= 12
840 for (
int to{j + k}; xy != 0 && to < (2 * parts); ++to) {
842 for (
int to{j + k}; xy != 0; ++to) {
845 product[to] = xy & partMask;
852 Integer upper{
nullptr}, lower{
nullptr};
853 for (
int j{0}; j < parts; ++j) {
854 lower.LEPart(j) = product[j];
855 upper.LEPart(j) = product[j + parts];
857 if constexpr (topPartBits < partBits) {
858 upper = upper.SHIFTL(partBits - topPartBits);
859 upper.LEPart(0) |= lower.LEPart(parts - 1) >> topPartBits;
860 lower.LEPart(parts - 1) &= topPartMask;
862 return {upper, lower};
865 constexpr Product MultiplySigned(
const Integer &y)
const {
866 bool yIsNegative{y.IsNegative()};
869 absy = y.Negate().value;
871 bool isNegative{IsNegative()};
874 absx = Negate().value;
876 Product product{absx.MultiplyUnsigned(absy)};
877 if (isNegative != yIsNegative) {
878 product.lower = product.lower.NOT();
879 product.upper = product.upper.NOT();
881 auto incremented{product.lower.AddUnsigned(one)};
882 product.lower = incremented.value;
883 if (incremented.carry) {
884 product.upper = product.upper.AddUnsigned(one).value;
890 constexpr QuotientWithRemainder DivideUnsigned(
const Integer &divisor)
const {
891 if (divisor.IsZero()) {
892 return {MASKR(bits),
Integer{},
true,
false};
894 int bitsDone{LEADZ()};
897 for (; bitsDone < bits; ++bitsDone) {
898 auto doubledTop{top.AddUnsigned(top)};
899 top = doubledTop.value;
900 remainder = remainder.AddUnsigned(remainder, doubledTop.carry).value;
901 bool nextBit{remainder.CompareUnsigned(divisor) != Ordering::Less};
902 quotient = quotient.AddUnsigned(quotient, nextBit).value;
904 remainder = remainder.SubtractSigned(divisor).value;
907 return {quotient, remainder,
false,
false};
913 constexpr QuotientWithRemainder DivideSigned(
Integer divisor)
const {
914 bool dividendIsNegative{IsNegative()};
915 bool negateQuotient{dividendIsNegative};
916 Ordering divisorOrdering{divisor.CompareToZeroSigned()};
917 if (divisorOrdering == Ordering::Less) {
918 negateQuotient = !negateQuotient;
919 auto negated{divisor.Negate()};
920 if (negated.overflow) {
922 if (CompareUnsigned(divisor) == Ordering::Equal) {
923 return {MASKR(1),
Integer{},
false, bits <= 1};
925 return {
Integer{}, *
this,
false,
false};
928 divisor = negated.value;
929 }
else if (divisorOrdering == Ordering::Equal) {
931 if (dividendIsNegative) {
932 return {MASKL(1),
Integer{},
true,
false};
934 return {MASKR(bits - 1),
Integer{},
true,
false};
938 if (dividendIsNegative) {
939 auto negated{Negate()};
940 if (negated.overflow) {
943 if (divisorOrdering == Ordering::Less &&
944 divisor.CompareUnsigned(
Integer{1}) == Ordering::Equal) {
946 return {*
this,
Integer{},
false,
true};
949 dividend = negated.value;
954 QuotientWithRemainder result{dividend.DivideUnsigned(divisor)};
955 if (negateQuotient) {
956 result.quotient = result.quotient.Negate().value;
958 if (dividendIsNegative) {
959 result.remainder = result.remainder.Negate().value;
966 constexpr ValueWithOverflow MODULO(
const Integer &divisor)
const {
967 bool negativeDivisor{divisor.IsNegative()};
968 bool distinctSigns{IsNegative() != negativeDivisor};
969 QuotientWithRemainder divided{DivideSigned(divisor)};
970 if (distinctSigns && !divided.remainder.IsZero()) {
971 return {divided.remainder.AddUnsigned(divisor).value, divided.overflow};
973 return {divided.remainder, divided.overflow};
977 constexpr PowerWithErrors Power(
const Integer &exponent)
const {
978 PowerWithErrors result{1,
false,
false,
false};
979 if (exponent.IsZero()) {
986 result.zeroToZero = IsZero();
987 }
else if (exponent.IsNegative()) {
989 result.divisionByZero =
true;
990 result.power = MASKR(bits - 1);
991 }
else if (CompareSigned(
Integer{1}) == Ordering::Equal) {
992 result.power = *
this;
993 }
else if (CompareSigned(
Integer{-1}) == Ordering::Equal) {
994 if (exponent.BTEST(0)) {
995 result.power = *
this;
998 result.power.Clear();
1003 int nbits{bits - pow.LEADZ()};
1004 for (
int j{0}; j < nbits; ++j) {
1006 Product product{result.power.MultiplySigned(shifted)};
1007 result.power = product.lower;
1008 result.overflow |= product.SignedMultiplicationOverflowed();
1010 if (j + 1 < nbits) {
1011 Product squared{shifted.MultiplySigned(shifted)};
1012 result.overflow |= squared.SignedMultiplicationOverflowed();
1013 shifted = squared.lower;
1024 constexpr Integer(std::nullptr_t) {}
1027 constexpr const Part &LEPart(
int part)
const {
1028 if constexpr (littleEndian) {
1031 return part_[parts - 1 - part];
1035 constexpr Part &LEPart(
int part) {
1036 if constexpr (littleEndian) {
1039 return part_[parts - 1 - part];
1043 constexpr void SetLEPart(
int part, Part x) {
1044 LEPart(part) = x & PartMask(part);
1047 static constexpr Part PartMask(
int part) {
1048 return part == parts - 1 ? topPartMask : partMask;
1051 constexpr void Clear() {
1052 for (
int j{0}; j < parts; ++j) {
1057 Part part_[partsWithAlignment]{};