60class Nat :
public Limb<W64> {
62 using Super = Limb<W64>;
64 using limb_t =
typename Super::limb_t;
70 static constexpr size_t kMaxStringLen = 20 * W64 + 1;
73 explicit Nat(uint64_t x) : Super(x) {}
75 explicit Nat(
const std::array<uint64_t, kU64>& a) : Super(a) {}
83 const char* s = ss.as_pointer;
84 if (s[0] ==
'0' && (s[1] ==
'x' || s[1] ==
'X')) {
90 bool ok = muls(limb_, base);
91 check(ok,
"overflow in nat(const char *s)");
92 limb_t ah = add_limb(kLimbs, limb_, d.limb_);
93 check(ah == 0,
"overflow in nat(const char *s)");
98 explicit Nat(
const char (&p)[LEN]) : Nat(
StaticString(p)) {}
101 static T of_bytes(
const uint8_t a[]) {
103 for (
size_t i = 0; i < kLimbs; ++i) {
104 a = Super::of_bytes(&r.limb_[i], a);
109 static std::optional<unsigned> safe_digit(
char c, limb_t base) {
111 if (c >=
'0' && c <=
'9') {
113 }
else if (base == 16u && c >=
'a' && c <=
'f') {
119 static std::optional<T> of_untrusted_string(
const char* s) {
122 if (s[0] ==
'0' && (s[1] ==
'x' || s[1] ==
'X')) {
127 for (
size_t len = 0; len < kMaxStringLen && *p; ++len, ++p) {
128 auto d = safe_digit(*p, base);
129 if (!d.has_value()) {
133 if (!muls(r.limb_, base)) {
136 limb_t ah = add_limb(kLimbs, r.limb_, td.limb_);
149 bool operator<(
const T& y)
const {
151 limb_t bh = sub_limb(kLimbs, b.limb_, y.limb_);
156 (void)add_limb(kLimbs, limb_, y.limb_);
160 (void)sub_limb(kLimbs, limb_, y.limb_);
166 static bool muls(limb_t b[kLimbs], limb_t a) {
168 mulhl(kLimbs, b, h, a, b);
169 limb_t bh = addh(kLimbs, b, h);