Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
zm.h
Go to the documentation of this file.
1#pragma once
6#include <vector>
7#include <string>
8#include <cassert>
9#include <string>
10#include <stdio.h>
11#include <stdlib.h>
12#include <sstream>
13#include <iomanip>
14#include <stdexcept>
15#include <algorithm>
16#include <iostream>
17
18#ifndef MIE_ZM_VUINT_BIT_LEN
19 // minimum 512
20 #define MIE_ZM_VUINT_BIT_LEN (64 * 9)
21#endif
22
23#define MIE_USE_X64ASM
24
25#ifdef _MSC_VER
26 #include <intrin.h>
27 #include <malloc.h>
28#endif
29#if !defined(_MSC_VER) || (_MSC_VER >= 1600)
30 #include <stdint.h>
31#else
32 typedef unsigned __int64 uint64_t;
33 typedef __int64 int64_t;
34 typedef unsigned int uint32_t;
35 typedef int int32_t;
36#endif
37
38#ifdef _MSC_VER
39 #ifndef MIE_ALIGN
40 #define MIE_ALIGN(x) __declspec(align(x))
41 #endif
42 #ifndef MIE_FORCE_INLINE
43 #define MIE_FORCE_INLINE __forceinline
44 #endif
45 #ifndef MIE_ALLOCA_
46 #define MIE_ALLOCA_(x) _alloca(x)
47 #endif
48#else
49 #ifndef MIE_ALIGN
50 #define MIE_ALIGN(x) __attribute__((aligned(16)))
51 #endif
52 #ifndef MIE_FORCE_INLINE
53 #define MIE_FORCE_INLINE __attribute__((always_inline))
54 #endif
55 #ifndef MIE_ALLOCA_
56 #define MIE_ALLOCA_(x) __builtin_alloca(x)
57 #endif
58#endif
59
60namespace mie {
61
62#if defined(_WIN64) || defined(__x86_64__)
63 typedef uint64_t Unit;
64 #define MIE_USE_UNIT64
65#else
66 typedef uint32_t Unit;
67 #define MIE_USE_UNIT32
68 #undef MIE_USE_X64ASM
69#endif
70
71static inline uint64_t make64(uint32_t H, uint32_t L)
72{
73 return ((uint64_t)H << 32) | L;
74}
75
76static inline void split64(uint32_t *H, uint32_t *L, uint64_t x)
77{
78 *H = uint32_t(x >> 32);
79 *L = uint32_t(x);
80}
81
82namespace local {
83
84inline std::istream& getDigits(std::istream& is, std::string& str, bool allowNegative = false)
85{
86 std::ios_base::fmtflags keep = is.flags();
87 size_t pos = 0;
88 char c;
89 while (is >> c) {
90 if (('0' <= c && c <= '9') /* digits */
91 || (pos == 1 && (str[0] == '0' && c == 'x')) /* 0x.. */
92 || ('a' <= c && c <= 'f') /* lowercase hex */
93 || ('A' <= c && c <= 'F') /* uppercase hex */
94 || (allowNegative && pos == 0 && c == '-')) { /* -digits */
95 str.push_back(c);
96 if (pos == 0) {
97 is >> std::noskipws;
98 }
99 pos++;
100 } else {
101 is.unget();
102 break;
103 }
104 }
105 is.flags(keep);
106 return is;
107}
108
109
110static inline void errExit(const std::string& msg = "")
111{
112 printf("err %s\n", msg.c_str());
113 exit(1);
114}
115
116/*
117 T must have compare, add, sub, mul
118*/
119template<class T>
120struct Empty {};
121
122template<class T, class E = Empty<T> >
123struct comparable : E {
124 MIE_FORCE_INLINE friend bool operator<(const T& x, const T& y) { return T::compare(x, y) < 0; }
125 MIE_FORCE_INLINE friend bool operator>=(const T& x, const T& y) { return !operator<(x, y); }
126
127 MIE_FORCE_INLINE friend bool operator>(const T& x, const T& y) { return T::compare(x, y) > 0; }
128 MIE_FORCE_INLINE friend bool operator<=(const T& x, const T& y) { return !operator>(x, y); }
129 MIE_FORCE_INLINE friend bool operator==(const T& x, const T& y) { return T::compare(x, y) == 0; }
130 MIE_FORCE_INLINE friend bool operator!=(const T& x, const T& y) { return !operator==(x, y); }
131};
132
133template<class T, class E = Empty<T> >
134struct addsubmul : E {
135 template<class N>
136 MIE_FORCE_INLINE T& operator+=(const N& rhs) { T::add(static_cast<T&>(*this), static_cast<T&>(*this), rhs); return static_cast<T&>(*this); }
137 MIE_FORCE_INLINE T& operator-=(const T& rhs) { T::sub(static_cast<T&>(*this), static_cast<T&>(*this), rhs); return static_cast<T&>(*this); }
138 MIE_FORCE_INLINE T& operator*=(const T& rhs) { T::mul(static_cast<T&>(*this), static_cast<T&>(*this), rhs); return static_cast<T&>(*this); }
139 MIE_FORCE_INLINE friend T operator+(const T& a, const T& b) { T c; T::add(c, a, b); return c; }
140 MIE_FORCE_INLINE friend T operator-(const T& a, const T& b) { T c; T::sub(c, a, b); return c; }
141 MIE_FORCE_INLINE friend T operator*(const T& a, const T& b) { T c; T::mul(c, a, b); return c; }
142};
143
144template<class T, class E = Empty<T> >
145struct dividable : E {
146 MIE_FORCE_INLINE T& operator/=(const T& rhs) { T rdummy; T::div(static_cast<T*>(this), rdummy, static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
147 MIE_FORCE_INLINE T& operator%=(const T& rhs) { T::div(0, static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
148
149 MIE_FORCE_INLINE friend T operator/(const T& a, const T& b) { T q, r; T::div(&q, r, a, b); return q; }
150 MIE_FORCE_INLINE friend T operator%(const T& a, const T& b) { T r; T::div(0, r, a, b); return r; }
151};
152
153template<class T, class E = Empty<T> >
154struct hasNegative : E {
155 MIE_FORCE_INLINE T operator-() const { T c; T::neg(c, static_cast<const T&>(*this)); return c; }
156};
157
158template<class T, class E = Empty<T> >
159struct shiftable : E {
160 MIE_FORCE_INLINE T operator<<(size_t n) const { T out; T::shl(out, static_cast<const T&>(*this), n); return out; }
161 MIE_FORCE_INLINE T operator>>(size_t n) const { T out; T::shr(out, static_cast<const T&>(*this), n); return out; }
162
163// T& operator<<=(size_t n) { *this = *this << n; return static_cast<T&>(*this); }
164// T& operator>>=(size_t n) { *this = *this >> n; return static_cast<T&>(*this); }
165 MIE_FORCE_INLINE T& operator<<=(size_t n) { T::shl(static_cast<T&>(*this), static_cast<const T&>(*this), n); return static_cast<T&>(*this); }
166 MIE_FORCE_INLINE T& operator>>=(size_t n) { T::shr(static_cast<T&>(*this), static_cast<const T&>(*this), n); return static_cast<T&>(*this); }
167};
168
169template<class T, class E = Empty<T> >
170struct inversible : E {
171 MIE_FORCE_INLINE void inverse() { T& self = static_cast<T&>(*this);T out; T::inv(out, self); self = out; }
172 MIE_FORCE_INLINE friend T operator/(const T& x, const T& y) { T out; T::inv(out, y); out *= x; return out; }
173 MIE_FORCE_INLINE T& operator/=(const T& x) { T rx; T::inv(rx, x); T& self = static_cast<T&>(*this); self *= rx; return self; }
174};
175
177 /*
178 compare x[] and y[]
179 @retval positive if x > y
180 @retval 0 if x == y
181 @retval negative if x < y
182 */
183 static inline int compare(const Unit *x, size_t xn, const Unit *y, size_t yn)
184 {
185 assert(xn > 0 && yn > 0);
186 if (xn != yn) return xn > yn ? 1 : -1;
187 for (int i = (int)xn - 1; i >= 0; i--) {
188 if (x[i] != y[i]) return x[i] > y[i] ? 1 : -1;
189 }
190 return 0;
191 }
192 /*
193 out[] = x[] + y[]
194 out may be equal to x or y
195 */
196 static bool (*addN)(Unit *out, const Unit *x, const Unit *y, size_t n);
197 /*
198 out[] = x[] + y
199 */
200 static bool (*add1)(Unit *out, const Unit *x, size_t n, Unit y);
201 /*
202 out[] = x[] - y[]
203 out may be equal to x or y
204 */
205 static bool (*subN)(Unit *out, const Unit *x, const Unit *y, size_t n);
206 /*
207 out[] = x[] - y
208 */
209 static bool (*sub1)(Unit *out, const Unit *x, size_t n, Unit y);
210
211 static void (*mul1)(Unit *out, const Unit *x, size_t n, Unit y);
212
213 /*
214 q[] = x[] / y
215 @retval r = x[] % y
216 q may be equal to x
217 */
218 static Unit (*div1)(Unit *q, const Unit *x, size_t n, Unit y);
219 /*
220 q[] = x[] / y
221 @retval r = x[] % y
222 */
223 static Unit (*mod1)(const Unit *x, size_t n, Unit y);
224};
225
226template<class T, size_t = 0>
228 std::vector<T> v_;
229public:
230 typedef T value_type;
232 {
233 }
234 void clear() { v_.clear(); }
235
236 /*
237 @note extended buffer may be not cleared
238 */
239 void alloc(size_t n)
240 {
241#if NDEBUG
242 v_.resize(n);
243#else
244 size_t m = v_.size();
245 v_.resize(n);
246 if (n > m) {
247 std::fill(&v_[0] + m, &v_[0] + n, (T)-1);
248 }
249#endif
250 }
251
252 /*
253 *this = rhs
254 rhs may be destroyed
255 */
256 void moveFrom(VariableBuffer& rhs) { v_.swap(rhs.v_); }
257 size_t size() const { return v_.size(); }
258 const T& operator[](size_t n) const { return v_[n]; }
259 T& operator[](size_t n) { return v_[n]; }
260};
261
262template<class T, size_t BitLen>
264 enum {
265 N = (BitLen + sizeof(T) * 8 - 1) / (sizeof(T) * 8)
266 };
267 T v_[N];
268 size_t size_;
269public:
270 typedef T value_type;
272 : size_(0)
273 {
274 }
276 {
277 operator=(rhs);
278 }
280 {
281 size_ = rhs.size_;
282 std::copy(rhs.v_, rhs.v_ + rhs.size_, v_);
283 return *this;
284 }
285 void clear() { size_ = 0; }
286 void alloc(size_t n)
287 {
288 verify(n);
289 size_ = n;
290 }
291 void forceAlloc(size_t n) // for placement new
292 {
293 size_ = n;
294 }
295 size_t size() const { return size_; }
296 void moveFrom(const FixedBuffer& rhs)
297 {
298 operator=(rhs);
299 }
300 // to avoid warning of gcc
301 void verify(size_t n) const
302 {
303 if (n > N) {
304 printf("n=%d, N=%d\n", (int)n, (int)N);
305 local::errExit("too large size. increase MIE_ZM_VUINT_BIT_LEN in include/zm.h");
306 }
307 }
308 const T& operator[](size_t n) const { verify(n); return v_[n]; }
309 T& operator[](size_t n) { verify(n); return v_[n]; }
310};
311
312} // local
313
317template<class Buffer>
318struct VuintT : public local::dividable<VuintT<Buffer>,
319 local::addsubmul<VuintT<Buffer>,
320 local::comparable<VuintT<Buffer>,
321 local::shiftable<VuintT<Buffer>, Buffer> > > > {
322 typedef local::PrimitiveFunction F;
323 typedef typename Buffer::value_type T;
324
325 VuintT(T x = 0)
326 {
327 set(x);
328 }
329 explicit VuintT(const std::string& str)
330 {
331 set(str);
332 }
333 VuintT(const uint32_t *x, size_t size)
334 {
335 set(x, size);
336 }
337 VuintT(const uint64_t *x, size_t size)
338 {
339 set(x, size);
340 }
341 void set(T x)
342 {
343 Buffer::alloc(1);
344 (*this)[0] = x;
345 }
346 void set(const uint32_t *x, size_t size)
347 {
348 Buffer::clear();
349 if (size == 0) {
350 set((T)0);
351 return;
352 }
353#ifdef MIE_USE_UNIT32
354 Buffer::alloc(size);
355 for (size_t i = 0; i < size; i++) {
356 (*this)[i] = x[i];
357 }
358#else
359 Buffer::alloc((size + 1) / 2);
360 for (size_t i = 0; i < size / 2; i++) {
361 (*this)[i] = make64(x[i * 2 + 1], x[i * 2]);
362 }
363 if (size & 1) {
364 (*this)[size / 2] = x[size - 1];
365 }
366#endif
367 trim();
368 }
369 void set(const uint64_t *x, size_t size)
370 {
371 Buffer::clear();
372 if (size == 0) {
373 set((T)0);
374 return;
375 }
376#ifdef MIE_USE_UNIT32
377 Buffer::alloc(size * 2);
378 for (size_t i = 0; i < size; i++) {
379 uint32_t L, H;
380 split64(&H, &L, x[i]);
381 (*this)[i * 2 + 0] = L;
382 (*this)[i * 2 + 1] = H;
383 }
384#else
385 Buffer::alloc(size);
386 for (size_t i = 0; i < size; i++) {
387 (*this)[i] = x[i];
388 }
389#endif
390 trim();
391 }
392
393 /***
394 If an index refer to the out of valid range,
395 then it returns 0.
396 */
397 T getAtWithCheck(size_t i) const
398 {
399 if (i >= this->size()) {
400 return 0;
401 } else {
402 return (*this)[i];
403 }
404 }
405
406 void clear() { set((T)0); }
407 std::string toString(int base = 10) const
408 {
409 std::ostringstream os;
410 switch (base) {
411 case 10:
412 {
413 const uint32_t i1e9 = 1000000000U;
414 static const VuintT zero = 0;
415 VuintT x = *this;
416
417 std::vector<uint32_t> t;
418 while (x > zero) {
419 uint32_t r = (uint32_t)div1(&x, x, i1e9);
420 t.push_back(r);
421 }
422 if (t.empty()) {
423 return "0";
424 }
425 os << t[t.size() - 1];
426 for (size_t i = 1, n = t.size(); i < n; i++) {
427 os << std::setfill('0') << std::setw(9) << t[n - 1 - i];
428 }
429 }
430 break;
431 case 16:
432 {
433 os << "0x" << std::hex;
434 const size_t n = Buffer::size();
435 os << (*this)[n - 1];
436 for (size_t i = 1; i < n; i++) {
437 os << std::setfill('0') << std::setw(sizeof(Unit) * 2) << (*this)[n - 1 - i];
438 }
439 }
440 break;
441 default:
442 local::errExit("toString not support base");
443 }
444 return os.str();
445 }
446 /*
447 @param str [in] number string
448 @note "0x..." => base = 16
449 "0b..." => base = 2
450 otherwise => base = 10
451 */
452 void set(const std::string& str, int base = 0)
453 {
454 std::string t;
455 if (str.size() >= 2 && str[0] == '0') {
456 switch (str[1]) {
457 case 'x':
458 if (base != 0 && base != 16) local::errExit("bad base in set(str)");
459 base = 16;
460 t = str.substr(2);
461 break;
462 default:
463 local::errExit("not support base in set(str) 0x");
464 }
465 }
466 if (base == 0) {
467 base = 10;
468 }
469 if (t.empty()) t = str;
470
471 switch (base) {
472 case 16:
473 {
474 std::vector<uint32_t> x;
475 while (!t.empty()) {
476 size_t remain = std::min((int)t.size(), 8);
477 char *endp;
478 uint32_t v = strtoul(&t[t.size() - remain], &endp, 16);
479 if (*endp) goto ERR;
480 x.push_back(v);
481 t = t.substr(0, t.size() - remain);
482 }
483 set(&x[0], x.size());
484 }
485 break;
486 default:
487 case 10:
488 {
489 std::vector<uint32_t> x;
490 while (!t.empty()) {
491 size_t remain = std::min((int)t.size(), 9);
492 char *endp;
493 uint32_t v = strtol(&t[t.size() - remain], &endp, 10);
494 if (*endp) goto ERR;
495 x.push_back(v);
496 t = t.substr(0, t.size() - remain);
497 }
498 clear();
499 for (size_t i = 0, n = x.size(); i < n; i++) {
500 (*this) *= 1000000000;
501 (*this) += x[n - 1 - i];
502 }
503 }
504 break;
505 }
506 return;
507 ERR:
508 throw std::invalid_argument(std::string("bad digit `") + str + "`");
509 }
510 void fromStr(const std::string& str, int base = 10)
511 {
512 set(str, base);
513 }
514 std::string toStr(int base = 10) const { return toString(base); }
515 static int compare(const VuintT& x, const VuintT& y)
516 {
517 return F::compare(&x[0], x.size(), &y[0], y.size());
518 }
519 size_t size() const { return Buffer::size(); }
520
521 bool isZero() const
522 {
523 return Buffer::size() == 1 && (*this)[0] == 0;
524 }
525
526 size_t bitLen() const
527 {
528 if (isZero()) return 0;
529
530 size_t size = this->size();
531 T v = (*this)[size - 1];
532 union di t;
533 t.f = (double)v;
534 size_t ret = 1 + (size_t(t.i >> 52) - (1 << 10) + 1) +
535 (size - 1) * sizeof(T) * 8;
536 return ret;
537 }
538
539 bool testBit(size_t i) const
540 {
541 size_t unit_pos = i / (sizeof(T) * 8);
542 size_t bit_pos = i % (sizeof(T) * 8);
543 T mask = T(1) << bit_pos;
544 return ((*this)[unit_pos] & mask) != 0;
545 }
546
547 static bool add_in(VuintT& out, const VuintT& x, const VuintT& y)
548 {
549 const VuintT *px = &x;
550 const VuintT *py = &y;
551 if (y.size() > x.size()) {
552 std::swap(px, py);
553 }
554 size_t max = px->size();
555 size_t min = py->size();
556 out.alloc(max);
557 bool c = F::addN(&out[0], &(*px)[0], &(*py)[0], min);
558 if (max > min) {
559 c = F::add1(&out[min], &(*px)[min], max - min, c);
560 }
561 return c;
562 }
563
564 static inline void add(VuintT& out, const VuintT& x, const VuintT& y)
565 {
566 bool c = add_in(out, x, y);
567 if (c) {
568 out.alloc(out.size() + 1);
569 out[out.size() - 1] = 1;
570 } else {
571 out.trim();
572 }
573 }
574 static inline void add(VuintT& out, const VuintT& x, uint32_t y)
575 {
576 const size_t n = x.size();
577 out.alloc(n);
578 bool c = F::add1(&out[0], &x[0], n, y);
579 if (c) {
580 out.alloc(n + 1);
581 out[n] = 1;
582 }
583 }
584 static bool sub_in(VuintT& out, const VuintT& x, const VuintT& y)
585 {
586 const size_t xn = x.size();
587 const size_t yn = y.size();
588 assert(xn >= yn);
589 out.alloc(xn);
590 bool c = F::subN(&out[0], &x[0], &y[0], yn);
591 if (xn > yn) {
592 c = F::sub1(&out[yn], &x[yn], xn - yn, c);
593 }
594 return c;
595 }
596
597 static void sub(VuintT& out, const VuintT& x, const VuintT& y)
598 {
599 bool c = sub_in(out, x, y);
600 if (c) {
601 local::errExit("can't sub");
602 }
603 out.trim();
604 }
605
606 static void mul1(VuintT& out, const VuintT& x, T y)
607 {
608 const size_t xn = x.size();
609 out.alloc(xn + 1);
610 F::mul1(&out[0], &x[0], xn, y);
611 out.trim();
612 }
613 static void mul(VuintT& out, const VuintT& x, const VuintT& y)
614 {
615 const size_t xn = x.size();
616 const size_t yn = y.size();
617
618 VuintT xt, yt;
619 const Unit *px = &x[0], *py = &y[0];
620 if (&out == &x) {
621 xt = x;
622 px = &xt[0];
623 }
624 if (&out == &y) {
625 if (&x == &y) {
626 py = px;
627 } else {
628 yt = y;
629 py = &yt[0];
630 }
631 }
632 out.alloc(xn + yn);
633 mul(&out[0], px, xn, py, yn);
634 out.trim();
635 }
642 static T div1(VuintT *q, const VuintT& x, T y)
643 {
644 const size_t xn = x.size();
645 T r;
646 if (q) {
647 q->alloc(xn); // assume q is not destroyed if q == x
648 r = F::div1(&(*q)[0], &x[0], xn, y);
649 q->trim();
650 } else {
651 r = F::mod1(&x[0], xn, y);
652 }
653 return r;
654 }
661 static bool div(VuintT* q, VuintT& r, const VuintT& x, const VuintT& y)
662 {
663//std::cout << "x=" << x << std::endl;
664//std::cout << "y=" << y << std::endl;
665 assert(q != &r);
666 const size_t xn = x.size();
667 const size_t yn = y.size();
668 if (yn == 1) {
669 if (y[0] == 0) return false;
670 r.set(div1(q, x, y[0]));
671 return true;
672 }
673 int cmp = F::compare(&x[0], xn, &y[0], yn);
674 if (cmp < 0) {
675 if (&r != &x) {
676 r = x;
677 }
678 if (q) q->clear();
679 } else if (cmp == 0) {
680 // imply &x == &y
681 if (q) q->set(1);
682 r.clear();
683 } else {
684 assert(&x != &y);
685 VuintT qt;
686 Unit *pqt = 0;
687 bool directQ = false;
688 if (q == 0) {
689 pqt = 0;
690 } else if (q != &x && q != &y) {
691 q->alloc(xn - yn + 1);
692 pqt = &(*q)[0];
693 directQ = true;
694 } else {
695 qt.alloc(xn - yn + 1);
696 pqt = &qt[0];
697 }
698 VuintT rt;
699 Unit *prt = 0;
700 bool directR = false;
701 if (&r != &x && &r != &y) {
702 r = x;
703 directR = true;
704 prt = &r[0];
705 } else {
706 rt = x;
707 prt = &rt[0];
708 }
709 div(pqt, prt, xn, &y[0], yn);
710 if (q) {
711 if (directQ) {
712 q->trim();
713 } else {
714 qt.trim();
715 q->moveFrom(qt);
716 }
717 }
718 if (directR) {
719 r.trim();
720 } else {
721 rt.trim();
722 r.moveFrom(rt);
723 }
724 }
725//puts("out");
726 return true;
727 }
728 inline friend std::ostream& operator<<(std::ostream& os, const VuintT& x)
729 {
730 return os << x.toString(os.flags() & std::ios_base::hex ? 16 : 10);
731 }
732 inline friend std::istream& operator>>(std::istream& is, VuintT& x)
733 {
734 std::string str;
735 local::getDigits(is, str);
736 x.set(str);
737 return is;
738 }
739
740 /*
741 shift left Unit
742 */
743 static inline void shlUnit(VuintT& out, const VuintT& x, size_t n)
744 {
745 const size_t xn = x.size();
746 out.alloc(xn + n);
747 for (int i = (int)xn - 1; i >= 0; i--) {
748 out[i + n] = x[i];
749 }
750 std::fill(&out[0], &out[0] + n, 0);
751 out.trim();
752 }
753 /*
754 shift left bit
755 0 < n < sizeof(T)
756 */
757 static inline void shlBit(VuintT& out, const VuintT& x, size_t n)
758 {
759 const size_t unitSize = sizeof(T) * 8;
760 assert(0 < n && n < unitSize);
761 const size_t xn = x.size();
762 out.alloc(xn);
763
764 T prev = 0;
765 size_t rn = unitSize - n;
766 for (size_t i = 0; i < xn; i++) {
767 T t = x[i];
768 out[i] = (t << n) | (prev >> rn);
769 prev = t;
770 }
771 prev >>= rn;
772 if (prev) {
773 out.alloc(xn + 1);
774 out[xn] = prev;
775 }
776 }
777 /*
778 shift right byte
779 */
780 static inline void shrUnit(VuintT& out, const VuintT& x, size_t n)
781 {
782 const size_t xn = x.size();
783 if (xn <= n) {
784 out = 0;
785 } else {
786 out.alloc(xn); // not on because of x may be equal to out
787 const size_t on = xn - n;
788 for (size_t i = 0; i < on; i++) {
789 out[i] = x[i + n];
790 }
791 out.alloc(on);
792 }
793 }
794 /*
795 shift right bit
796 0 < n < sizeof(T)
797 */
798 static inline void shrBit(VuintT& out, const VuintT& x, size_t n)
799 {
800 const size_t unitSize = sizeof(T) * 8;
801 assert(0 < n && n < unitSize);
802 const size_t xn = x.size();
803 T prev = 0;
804 size_t rn = unitSize - n;
805 out.alloc(xn);
806 for (int i = (int)xn - 1; i >= 0; i--) {
807 T t = x[i];
808 out[i] = (t >> n) | (prev << rn);
809 prev = t;
810 }
811 out.trim();
812 }
813 static inline void shl(VuintT& out, const VuintT& x, size_t n)
814 {
815 if (n == 0) {
816 out = x;
817 } else {
818 const size_t unitSize = sizeof(T) * 8;
819 size_t q = n / unitSize;
820 size_t r = n % unitSize;
821 const VuintT *p = &x;
822 if (q) {
823 shlUnit(out, x, q);
824 p = &out;
825 }
826 if (r) {
827 shlBit(out, *p, r);
828 }
829 }
830 }
831 static inline void shr(VuintT& out, const VuintT& x, size_t n)
832 {
833 if (n == 0) {
834 out = x;
835 } else {
836 const size_t unitSize = sizeof(T) * 8;
837 size_t q = n / unitSize;
838 size_t r = n % unitSize;
839 const VuintT *p = &x;
840 if (q) {
841 shrUnit(out, x, q);
842 p = &out;
843 }
844 if (r) {
845 shrBit(out, *p, r);
846 }
847 }
848 }
849private:
850 union di {
851 double f;
852 uint64_t i;
853 };
854 /*
855 get approximate value from x[xn - 1..]
856 @param up [in] round up if true
857 */
858 static inline double GetApp(const T *x, size_t xn, bool up)
859 {
860 assert(xn >= 2);
861 T H = x[xn - 1];
862 assert(H);
863 union di di;
864 di.f = (double)H;
865 unsigned int len = int(di.i >> 52) - 1023 + 1;
866#ifdef MIE_USE_UNIT32
867 uint32_t M = x[xn - 2];
868 if (len >= 21) {
869 di.i |= M >> (len - 21);
870 } else {
871 di.i |= uint64_t(M) << (21 - len);
872 if (xn >= 3) {
873 uint32_t L = x[xn - 3];
874 di.i |= L >> (len + 11);
875 }
876 }
877#else
878 if (len < 53) {
879 uint64_t L = x[xn - 2];
880 di.i |= L >> (len + 11);
881 } else {
882 // avoid rounding in converting from uint64_t to double
883 di.f = (double)(H & ~((uint64_t(1) << (len - 53)) - 1));
884 }
885#endif
886 double t = di.f;
887 if (up) {
888 di.i = uint64_t(len + 1022 - 52 + 1) << 52;
889 t += di.f;
890 }
891 return t;
892 }
893public:
894 void trim()
895 {
896 // remove leading zero
897 assert(Buffer::size());
898 int i = (int)Buffer::size() - 1;
899 for (; i > 0; i--) {
900 if ((*this)[i]) break;
901 }
902 Buffer::alloc(i ? i + 1: 1);
903 }
904 static inline void mul(T *out, const T *x, size_t xn, const T *y, size_t yn)
905 {
906 assert(xn > 0 && yn > 0);
907 if (yn > xn) {
908 std::swap(yn, xn);
909 std::swap(x, y);
910 }
911
912 std::fill(&out[xn + 1], &out[xn + yn], 0);
913 F::mul1(&out[0], x, xn, y[0]);
914
915#if 1
916 T *t2 = (T*)MIE_ALLOCA_(sizeof(T) * (xn + 1));
917#else
918 Buffer t2;
919 t2.alloc(xn + 1);
920#endif
921 for (size_t i = 1; i < yn; i++) {
922 F::mul1(&t2[0], x, xn, y[i]);
923 F::addN(&out[i], &out[i], &t2[0], xn + 1);
924 }
925 }
926 static inline void div(T *q, T *x, size_t xn, const T *y, size_t yn)
927 {
928 assert(xn >= yn && yn >= 2);
929 if (q) {
930 std::fill(q, q + xn - yn + 1, 0);
931 }
932 Buffer t;
933 t.alloc(yn + 1);
934 double yt = GetApp(y, yn, true);
935 while (F::compare(x, xn, y, yn) >= 0) {
936 size_t len = yn;
937 double xt = GetApp(x, xn, false);
938 if (F::compare(&x[xn - len], yn, y, yn) < 0) {
939 xt *= double(1ULL << (sizeof(T) * 8 - 1)) * 2;
940 len++;
941 }
942 T qt = T(xt / yt);
943 if (qt == 0) qt = 1;
944 F::mul1(&t[0], y, yn, qt);
945 bool b = F::subN(&x[xn - len], &x[xn - len], &t[0], len);
946 if (b) {
947 assert(!b);
948 }
949 if (q) q[xn - len] += qt;
950
951 while (xn >= yn && x[xn - 1] == 0) {
952 xn--;
953 }
954 }
955 }
956};
957
958template<class V>
959class VsintT : public local::addsubmul<VsintT<V>,
960 local::comparable<VsintT<V>,
961 local::dividable<VsintT<V>,
962 local::hasNegative<VsintT<V>,
963 local::shiftable<VsintT<V> > > > > > {
964 V v_;
965 bool isNeg_;
966public:
967 typedef typename V::value_type value_type;
968 VsintT(int x = 0)
969 : v_(::abs(x))
970 , isNeg_(x < 0)
971 {
972 }
973 explicit VsintT(const std::string& str)
974 {
975 set(str);
976 }
977 VsintT(const V& x)
978 : v_(x)
979 , isNeg_(false)
980 {
981 }
983 {
984 v_.set(x);
985 }
986 void set(int64_t x)
987 {
988 isNeg_ = x < 0;
989 v_.set(isNeg_ ? -x : x);
990 }
991 void set(const V& x)
992 {
993 v_ = x;
994 isNeg_ = false;
995 }
996 void set(const uint64_t *ptr, size_t size) { v_.set(ptr, size); }
997 const V& get() const { return v_; }
998 V& get() { return v_; }
999 void clear() { v_.set((value_type)0); isNeg_ = false; }
1000 std::string toString(int base = 10) const
1001 {
1002 if (isNeg_) return "-" + v_.toString(base);
1003 return v_.toString(base);
1004 }
1005 void set(const std::string& str, int base = 10)
1006 {
1007 isNeg_ = false;
1008 if (str.size() > 0 && str[0] == '-') {
1009 isNeg_ = true;
1010 v_.set(&str[1], base);
1011 } else {
1012 v_.set(str, base);
1013 }
1014 }
1015 void fromStr(const std::string& str, int base = 10)
1016 {
1017 set(str, base);
1018 }
1019 std::string toStr(int base = 10) { return toString(base); }
1020 static inline int compare(const VsintT& x, const VsintT& y)
1021 {
1022 if (x.isNeg_ ^ y.isNeg_) {
1023 if (x.isZero() && y.isZero()) return 0;
1024 return x.isNeg_ ? -1 : 1;
1025 } else {
1026 // same sign
1027 return V::compare(x.v_, y.v_) * (x.isNeg_ ? -1 : 1);
1028 }
1029 }
1030 size_t size() const { return v_.size(); }
1031 bool isZero() const { return v_.isZero(); }
1032 bool isNegative() const { return isNeg_ && !isZero(); }
1033 static inline void add(VsintT& out, const VsintT& x, const VsintT& y)
1034 {
1035 if ((x.isNeg_ ^ y.isNeg_) == 0) {
1036 // same sign
1037 V::add(out.v_, x.v_, y.v_);
1038 out.isNeg_ = x.isNeg_;
1039 return;
1040 }
1041 int r = V::compare(x.v_, y.v_);
1042 if (r >= 0) {
1043 V::sub(out.v_, x.v_, y.v_);
1044 out.isNeg_ = x.isNeg_;
1045 } else {
1046 V::sub(out.v_, y.v_, x.v_);
1047 out.isNeg_ = y.isNeg_;
1048 }
1049 }
1050 static inline void sub(VsintT& out, const VsintT& x, const VsintT& y)
1051 {
1052 if (x.isNeg_ ^ y.isNeg_) {
1053 // different sign
1054 V::add(out.v_, x.v_, y.v_);
1055 out.isNeg_ = x.isNeg_;
1056 return;
1057 }
1058 // same sign
1059 int r = V::compare(x.v_, y.v_);
1060 if (r >= 0) {
1061 V::sub(out.v_, x.v_, y.v_);
1062 out.isNeg_ = x.isNeg_;
1063 } else {
1064 V::sub(out.v_, y.v_, x.v_);
1065 out.isNeg_ = !y.isNeg_;
1066 }
1067 }
1068 static inline void mul(VsintT& out, const VsintT& x, const VsintT& y)
1069 {
1070 V::mul(out.v_, x.v_, y.v_);
1071 out.isNeg_ = x.isNeg_ ^ y.isNeg_;
1072 }
1073 static inline bool div(VsintT *q, VsintT& r, const VsintT& x, const VsintT& y)
1074 {
1075#if 1
1076 // like Python
1077 // 13 / -5 = -3 ... -2
1078 // -13 / 5 = -3 ... 2
1079 // -13 / -5 = 2 ... -3
1080 V yy = y.v_;
1081 bool ret = V::div(q ? &(q->v_) : 0, r.v_, x.v_, y.v_);
1082 if (!ret) return false;
1083 bool qsign = x.isNeg_ ^ y.isNeg_;
1084 if (r.v_.isZero()) {
1085 r.isNeg_ = false;
1086 } else {
1087 if (qsign) {
1088 if (q) {
1089 q->v_ += 1;
1090 }
1091 r.v_ = yy - r.v_;
1092 }
1093 r.isNeg_ = y.isNeg_;
1094 }
1095 if (q) q->isNeg_ = qsign;
1096 return true;
1097#else
1098 // 13 / -5 = -2 ... 3
1099 // -13 / 5 = -2 ... -3
1100 // -13 / -5 = 2 ... -3
1101 bool ret = V::div(q ? &(q->v_) : 0, r.v_, x.v_, y.v_);
1102 bool qsign = x.isNeg_ ^ y.isNeg_;
1103 r.isNeg_ = x.isNeg_;
1104 if (q) q->isNeg_ = qsign;
1105 return ret;
1106#endif
1107 }
1108 static inline void neg(VsintT& out, const VsintT& x)
1109 {
1110 out.v_ = x.v_;
1111 out.isNeg_ = !x.isNeg_;
1112 }
1113 inline friend std::ostream& operator<<(std::ostream& os, const VsintT& x)
1114 {
1115 if (x.isNeg_) os << "-";
1116 return os << x.v_;
1117 }
1118 inline friend std::istream& operator>>(std::istream& is, VsintT& x)
1119 {
1120 std::string str;
1121 local::getDigits(is, str, true);
1122 x.set(str);
1123 return is;
1124 }
1125 static inline void shl(VsintT& out, const VsintT& x, size_t n)
1126 {
1127 V::shl(out.v_, x.v_, n);
1128 out.isNeg_ = x.isNeg_;
1129 }
1130 static inline void shr(VsintT& out, const VsintT& x, size_t n)
1131 {
1132 if (x.isZero()) {
1133 out.clear();
1134 return;
1135 }
1136 if (x.isNeg_) {
1137 local::errExit("shr can't deal with negative value");
1138 } else {
1139 V::shr(out.v_, x.v_, n);
1140 out.isNeg_ = false;
1141 }
1142 }
1143
1144 static inline void absolute(V& out, const VsintT& in)
1145 {
1146 out = in.get();
1147 }
1148
1149 inline V abs() const { V x; absolute(x, *this); return x; }
1150 VsintT operator<<(size_t n) const
1151 {
1152 VsintT out; shl(out, *this, n); return out;
1153 }
1155 {
1156 shl(*this, *this, n); return *this;
1157 }
1158};
1159
1160//typedef VuintT<local::VariableBuffer> Vuint;
1163
1168template<class V = Vuint, class Tag = Vuint>
1169class ZmZ : public local::addsubmul<ZmZ<V, Tag>,
1170 local::comparable<ZmZ<V, Tag>,
1171 local::hasNegative<ZmZ<V, Tag>,
1172 local::inversible<ZmZ<V, Tag> > > > > {
1173public:
1174 typedef void base_type;
1175 typedef typename V::value_type value_type;
1176private:
1177 V v_;
1178 static V m_;
1179 void modulo()
1180 {
1181 v_ %= m_;
1182 }
1183public:
1184 ZmZ(int x = 0)
1185 {
1186 set(x);
1187 }
1188 explicit ZmZ(const std::string& str)
1189 {
1190 set(str);
1191 }
1192 ZmZ(const V& rhs)
1193 : v_(rhs)
1194 {
1195 modulo();
1196 }
1197 void set(const ZmZ &x) { v_ = x.v_; }
1198 void set(int x)
1199 {
1200 if (x == 0) {
1201 v_.clear();
1202 } else if (x > 0) {
1203 v_.set(x);
1204 } else {
1205 if (x == -2147483647 - 1 || m_ < -x) {
1206 local::errExit("x is too small");
1207 }
1208 v_ = m_;
1209 v_ -= -x;
1210 }
1211 }
1212 void set(const std::string& str)
1213 {
1214 v_.set(str);
1215 modulo();
1216 }
1217 void set(const uint32_t *x, size_t size)
1218 {
1219 v_.set(x, size);
1220 modulo();
1221 }
1222 void set(const uint64_t *x, size_t size)
1223 {
1224 v_.set(x, size);
1225 modulo();
1226 }
1227 void set(const V& rhs)
1228 {
1229 v_ = rhs;
1230 modulo();
1231 }
1232 static inline int compare(const ZmZ& x, const ZmZ& y)
1233 {
1234 return V::compare(x.v_, y.v_);
1235 }
1236 static inline void add(ZmZ& out, const ZmZ& x, const ZmZ& y)
1237 {
1238 V::add(out.v_, x.v_, y.v_);
1239 if (out.v_ >= m_) {
1240 out.v_ -= m_;
1241 }
1242 }
1243 static inline void sub(ZmZ& out, const ZmZ& x, const ZmZ& y)
1244 {
1245 if (x.v_ < y.v_) {
1246 if (&out != &y) {
1247 V::add(out.v_, x.v_, m_);
1248 out.v_ -= y.v_;
1249 } else {
1250 V t = x.v_ + m_;
1251 out.v_ = t - y.v_;
1252 }
1253 } else {
1254 V::sub(out.v_, x.v_, y.v_);
1255 }
1256 }
1257 static inline void neg(ZmZ& out, const ZmZ& x)
1258 {
1259 if (x.isZero()) {
1260 out = x;
1261 } else {
1262 V::sub(out.v_, m_, x.v_);
1263 }
1264 }
1265 static inline void mul(ZmZ& out, const ZmZ& x, const ZmZ& y)
1266 {
1267#if 0 // for only FixedBuffer(this code is dangerous and not good)
1268 const size_t xn = x.size();
1269 const size_t yn = y.size();
1270
1271 V *t = new(MIE_ALLOCA_(sizeof(value_type) * (xn + yn))) V;
1272 t->forceAlloc(xn + yn);
1273 V::mul(&(*t)[0], &x[0], xn, &y[0], yn);
1274 t->trim();
1275 V::div(0, out.v_, *t, m_);
1276 out.v_.trim();
1277#else
1278 V::mul(out.v_, x.v_, y.v_);
1279 out.modulo();
1280#endif
1281 }
1282 inline friend std::ostream& operator<<(std::ostream& os, const ZmZ& x)
1283 {
1284 return os << x.v_;
1285 }
1286 bool isZero() const { return v_.isZero(); }
1287 void clear() { v_ = 0; }
1288 const V& get() const { return v_; }
1289 /*
1290 out = 1/x mod m
1291 */
1292 static inline void inv(ZmZ& out, const ZmZ& x)
1293 {
1294 assert(!x.isZero());
1295 ZmZ a = 1;
1296 if (a.v_ == x.v_) {
1297 out = a;
1298 return;
1299 }
1300
1301 V t;
1302 ZmZ q;
1303 V::div(&q.v_, t, m_, x.v_);
1304 assert(!t.isZero()); // because m_ is prime
1305 V s = x.v_;
1306 ZmZ b = -q;
1307
1308 for (;;) {
1309 V::div(&q.v_, s, s, t);
1310 if (s.isZero()) {
1311 out = b;
1312 return;
1313 }
1314 a -= b * q;
1315
1316 V::div(&q.v_, t, t, s);
1317 if (t.isZero()) {
1318 out = a;
1319 return;
1320 }
1321 b -= a * q;
1322 }
1323 }
1324 std::string toString(int base = 10) const
1325 {
1326 return v_.toString(base);
1327 }
1328 const value_type& operator[](size_t i) const { return v_[i]; }
1329 value_type& operator[](size_t i) { return v_[i]; }
1330 size_t size() const { return v_.size(); }
1331 static void setModulo(const V& m)
1332 {
1333 m_ = m;
1334 }
1335 static inline const V& getModulo()
1336 {
1337 return m_;
1338 }
1339};
1340
1341namespace util {
1342/*
1343 dispatch Uint, int, size_t, and so on
1344*/
1345template<class T>
1346struct IntTag {
1347 typedef typename T::value_type value_type;
1348 static inline value_type getBlock(const T& x, size_t i)
1349 {
1350 return x[i];
1351 }
1352 static inline size_t getBlockSize(const T& x)
1353 {
1354 return x.size();
1355 }
1356};
1357
1358template<>
1359struct IntTag<int> {
1360 typedef int value_type;
1361 static inline value_type getBlock(const int& x, size_t)
1362 {
1363 return x;
1364 }
1365 static inline size_t getBlockSize(const int&)
1366 {
1367 return 1;
1368 }
1369};
1370template<>
1371struct IntTag<size_t> {
1372 typedef size_t value_type;
1373 static inline value_type getBlock(const size_t& x, size_t)
1374 {
1375 return x;
1376 }
1377 static inline size_t getBlockSize(const size_t&)
1378 {
1379 return 1;
1380 }
1381};
1382
1383} // util
1384
1388template<class T, class S>
1389T power(const T& x, const S& y)
1390{
1391 typedef typename mie::util::IntTag<S> Tag;
1392 typedef typename Tag::value_type value_type;
1393 T t(x);
1394 T out = 1;
1395 for (size_t i = 0, n = Tag::getBlockSize(y); i < n; i++) {
1396 value_type v = Tag::getBlock(y, i);
1397 int m = (int)sizeof(value_type) * 8;
1398 if (i == n - 1) {
1399 // avoid unused multiplication
1400 while (m > 0 && (v & (value_type(1) << (m - 1))) == 0) {
1401 m--;
1402 }
1403 }
1404 for (int j = 0; j < m; j++) {
1405 if (v & (value_type(1) << j)) {
1406 out *= t;
1407 }
1408 t *= t;
1409 }
1410 }
1411 return out;
1412}
1413
1414template<class V, class Tag>
1415V ZmZ<V, Tag>::m_;
1416
1417void zmInit();
1418
1419} // mie
const mie::Vuint & p
Definition bn.cpp:27
const mie::Vuint & r
Definition bn.cpp:28
friend std::istream & operator>>(std::istream &is, VsintT &x)
Definition zm.h:1118
V abs() const
Definition zm.h:1149
VsintT(int x=0)
Definition zm.h:968
static void absolute(V &out, const VsintT &in)
Definition zm.h:1144
void fromStr(const std::string &str, int base=10)
Definition zm.h:1015
void set(const std::string &str, int base=10)
Definition zm.h:1005
bool isNegative() const
Definition zm.h:1032
void clear()
Definition zm.h:999
void set(const uint64_t *ptr, size_t size)
Definition zm.h:996
void set(int64_t x)
Definition zm.h:986
static void shr(VsintT &out, const VsintT &x, size_t n)
Definition zm.h:1130
static void shl(VsintT &out, const VsintT &x, size_t n)
Definition zm.h:1125
VsintT(const V &x)
Definition zm.h:977
size_t size() const
Definition zm.h:1030
V & get()
Definition zm.h:998
V::value_type value_type
Definition zm.h:967
bool isZero() const
Definition zm.h:1031
VsintT(const std::string &str)
Definition zm.h:973
static int compare(const VsintT &x, const VsintT &y)
Definition zm.h:1020
std::string toString(int base=10) const
Definition zm.h:1000
friend std::ostream & operator<<(std::ostream &os, const VsintT &x)
Definition zm.h:1113
const V & get() const
Definition zm.h:997
VsintT & operator<<=(size_t n)
Definition zm.h:1154
void set(const V &x)
Definition zm.h:991
static void sub(VsintT &out, const VsintT &x, const VsintT &y)
Definition zm.h:1050
VsintT operator<<(size_t n) const
Definition zm.h:1150
static void add(VsintT &out, const VsintT &x, const VsintT &y)
Definition zm.h:1033
std::string toStr(int base=10)
Definition zm.h:1019
static bool div(VsintT *q, VsintT &r, const VsintT &x, const VsintT &y)
Definition zm.h:1073
static void neg(VsintT &out, const VsintT &x)
Definition zm.h:1108
static void mul(VsintT &out, const VsintT &x, const VsintT &y)
Definition zm.h:1068
void set(value_type x)
Definition zm.h:982
static void add(ZmZ &out, const ZmZ &x, const ZmZ &y)
Definition zm.h:1236
void set(const std::string &str)
Definition zm.h:1212
value_type & operator[](size_t i)
Definition zm.h:1329
friend std::ostream & operator<<(std::ostream &os, const ZmZ &x)
Definition zm.h:1282
ZmZ(const V &rhs)
Definition zm.h:1192
static void setModulo(const V &m)
Definition zm.h:1331
void set(const uint64_t *x, size_t size)
Definition zm.h:1222
void set(int x)
Definition zm.h:1198
void clear()
Definition zm.h:1287
static void mul(ZmZ &out, const ZmZ &x, const ZmZ &y)
Definition zm.h:1265
void set(const uint32_t *x, size_t size)
Definition zm.h:1217
static void sub(ZmZ &out, const ZmZ &x, const ZmZ &y)
Definition zm.h:1243
ZmZ(int x=0)
Definition zm.h:1184
V::value_type value_type
Definition zm.h:1175
void base_type
Definition zm.h:1174
size_t size() const
Definition zm.h:1330
const V & get() const
Definition zm.h:1288
void set(const ZmZ &x)
Definition zm.h:1197
std::string toString(int base=10) const
Definition zm.h:1324
static int compare(const ZmZ &x, const ZmZ &y)
Definition zm.h:1232
const value_type & operator[](size_t i) const
Definition zm.h:1328
void set(const V &rhs)
Definition zm.h:1227
ZmZ(const std::string &str)
Definition zm.h:1188
static void inv(ZmZ &out, const ZmZ &x)
Definition zm.h:1292
bool isZero() const
Definition zm.h:1286
static void neg(ZmZ &out, const ZmZ &x)
Definition zm.h:1257
static const V & getModulo()
Definition zm.h:1335
size_t size() const
Definition zm.h:295
void alloc(size_t n)
Definition zm.h:286
void verify(size_t n) const
Definition zm.h:301
FixedBuffer(const FixedBuffer &rhs)
Definition zm.h:275
FixedBuffer & operator=(const FixedBuffer &rhs)
Definition zm.h:279
void forceAlloc(size_t n)
Definition zm.h:291
const T & operator[](size_t n) const
Definition zm.h:308
T & operator[](size_t n)
Definition zm.h:309
void moveFrom(const FixedBuffer &rhs)
Definition zm.h:296
void alloc(size_t n)
Definition zm.h:239
size_t size() const
Definition zm.h:257
const T & operator[](size_t n) const
Definition zm.h:258
T & operator[](size_t n)
Definition zm.h:259
void moveFrom(VariableBuffer &rhs)
Definition zm.h:256
os_t os
#define ERR(name, desc)
Definition error.c:21
static const Reg16 di(Operand::DI)
std::istream & getDigits(std::istream &is, std::string &str, bool allowNegative=false)
Definition zm.h:84
Definition zm.h:60
void zmInit()
Definition zm.cpp:557
uint32_t Unit
Definition zm.h:66
T power(const T &x, const S &y)
Definition zm.h:1389
VsintT< Vuint > Vsint
Definition zm.h:1162
VuintT< local::FixedBuffer< mie::Unit, MIE_ZM_VUINT_BIT_LEN > > Vuint
Definition zm.h:1161
void swap(picojson::value &x, picojson::value &y)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
#define T(meth, val, expected)
const int N
Definition quantize.cpp:54
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
signed int int32_t
Definition stdint.h:123
unsigned __int64 uint64_t
Definition stdint.h:136
Definition test_zm.cpp:19
VuintT(T x=0)
Definition zm.h:325
VuintT(const uint64_t *x, size_t size)
Definition zm.h:337
static void shrUnit(VuintT &out, const VuintT &x, size_t n)
Definition zm.h:780
void set(const uint64_t *x, size_t size)
Definition zm.h:369
local::PrimitiveFunction F
Definition zm.h:322
size_t size() const
Definition zm.h:519
static T div1(VuintT *q, const VuintT &x, T y)
Definition zm.h:642
static void add(VuintT &out, const VuintT &x, const VuintT &y)
Definition zm.h:564
friend std::ostream & operator<<(std::ostream &os, const VuintT &x)
Definition zm.h:728
void set(const std::string &str, int base=0)
Definition zm.h:452
static void div(T *q, T *x, size_t xn, const T *y, size_t yn)
Definition zm.h:926
void clear()
Definition zm.h:406
static void shlUnit(VuintT &out, const VuintT &x, size_t n)
Definition zm.h:743
static void mul(T *out, const T *x, size_t xn, const T *y, size_t yn)
Definition zm.h:904
VuintT(const uint32_t *x, size_t size)
Definition zm.h:333
static void shlBit(VuintT &out, const VuintT &x, size_t n)
Definition zm.h:757
bool isZero() const
Definition zm.h:521
static void add(VuintT &out, const VuintT &x, uint32_t y)
Definition zm.h:574
static bool sub_in(VuintT &out, const VuintT &x, const VuintT &y)
Definition zm.h:584
static void shl(VuintT &out, const VuintT &x, size_t n)
Definition zm.h:813
static void shr(VuintT &out, const VuintT &x, size_t n)
Definition zm.h:831
static bool add_in(VuintT &out, const VuintT &x, const VuintT &y)
Definition zm.h:547
static int compare(const VuintT &x, const VuintT &y)
Definition zm.h:515
static void mul1(VuintT &out, const VuintT &x, T y)
Definition zm.h:606
size_t bitLen() const
Definition zm.h:526
static void shrBit(VuintT &out, const VuintT &x, size_t n)
Definition zm.h:798
void set(T x)
Definition zm.h:341
std::string toString(int base=10) const
Definition zm.h:407
std::string toStr(int base=10) const
Definition zm.h:514
T getAtWithCheck(size_t i) const
Definition zm.h:397
Buffer::value_type T
Definition zm.h:323
static void mul(VuintT &out, const VuintT &x, const VuintT &y)
Definition zm.h:613
void trim()
Definition zm.h:894
void fromStr(const std::string &str, int base=10)
Definition zm.h:510
static void sub(VuintT &out, const VuintT &x, const VuintT &y)
Definition zm.h:597
void set(const uint32_t *x, size_t size)
Definition zm.h:346
bool testBit(size_t i) const
Definition zm.h:539
friend std::istream & operator>>(std::istream &is, VuintT &x)
Definition zm.h:732
static bool div(VuintT *q, VuintT &r, const VuintT &x, const VuintT &y)
Definition zm.h:661
VuintT(const std::string &str)
Definition zm.h:329
static Unit(* div1)(Unit *q, const Unit *x, size_t n, Unit y)
Definition zm.h:218
static bool(* sub1)(Unit *out, const Unit *x, size_t n, Unit y)
Definition zm.h:209
static int compare(const Unit *x, size_t xn, const Unit *y, size_t yn)
Definition zm.h:183
static bool(* add1)(Unit *out, const Unit *x, size_t n, Unit y)
Definition zm.h:200
static void(* mul1)(Unit *out, const Unit *x, size_t n, Unit y)
Definition zm.h:211
static Unit(* mod1)(const Unit *x, size_t n, Unit y)
Definition zm.h:223
static bool(* subN)(Unit *out, const Unit *x, const Unit *y, size_t n)
Definition zm.h:205
static bool(* addN)(Unit *out, const Unit *x, const Unit *y, size_t n)
Definition zm.h:196
MIE_FORCE_INLINE friend T operator-(const T &a, const T &b)
Definition zm.h:140
MIE_FORCE_INLINE T & operator*=(const T &rhs)
Definition zm.h:138
MIE_FORCE_INLINE T & operator+=(const N &rhs)
Definition zm.h:136
MIE_FORCE_INLINE friend T operator*(const T &a, const T &b)
Definition zm.h:141
MIE_FORCE_INLINE friend T operator+(const T &a, const T &b)
Definition zm.h:139
MIE_FORCE_INLINE T & operator-=(const T &rhs)
Definition zm.h:137
MIE_FORCE_INLINE friend bool operator>(const T &x, const T &y)
Definition zm.h:127
MIE_FORCE_INLINE friend bool operator!=(const T &x, const T &y)
Definition zm.h:130
MIE_FORCE_INLINE friend bool operator==(const T &x, const T &y)
Definition zm.h:129
MIE_FORCE_INLINE friend bool operator<=(const T &x, const T &y)
Definition zm.h:128
MIE_FORCE_INLINE friend bool operator<(const T &x, const T &y)
Definition zm.h:124
MIE_FORCE_INLINE friend bool operator>=(const T &x, const T &y)
Definition zm.h:125
MIE_FORCE_INLINE friend T operator/(const T &a, const T &b)
Definition zm.h:149
MIE_FORCE_INLINE T & operator/=(const T &rhs)
Definition zm.h:146
MIE_FORCE_INLINE friend T operator%(const T &a, const T &b)
Definition zm.h:150
MIE_FORCE_INLINE T & operator%=(const T &rhs)
Definition zm.h:147
MIE_FORCE_INLINE T operator-() const
Definition zm.h:155
MIE_FORCE_INLINE void inverse()
Definition zm.h:171
MIE_FORCE_INLINE T & operator/=(const T &x)
Definition zm.h:173
MIE_FORCE_INLINE friend T operator/(const T &x, const T &y)
Definition zm.h:172
MIE_FORCE_INLINE T operator<<(size_t n) const
Definition zm.h:160
MIE_FORCE_INLINE T & operator>>=(size_t n)
Definition zm.h:166
MIE_FORCE_INLINE T operator>>(size_t n) const
Definition zm.h:161
MIE_FORCE_INLINE T & operator<<=(size_t n)
Definition zm.h:165
static value_type getBlock(const int &x, size_t)
Definition zm.h:1361
static size_t getBlockSize(const int &)
Definition zm.h:1365
static value_type getBlock(const size_t &x, size_t)
Definition zm.h:1373
static size_t getBlockSize(const size_t &)
Definition zm.h:1377
static size_t getBlockSize(const T &x)
Definition zm.h:1352
T::value_type value_type
Definition zm.h:1347
static value_type getBlock(const T &x, size_t i)
Definition zm.h:1348
void cmp(const Operand &op, uint32 imm)
CK_RV ret
char * s
uint16_t j
size_t len
bool set
#define MIE_ALLOCA_(x)
Definition zm.h:56
#define MIE_FORCE_INLINE
Definition zm.h:53