Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cBigUnsigned.h
Go to the documentation of this file.
1 //
4 //
5 #ifndef _INC_cBigUnsigned_H
6 #define _INC_cBigUnsigned_H
7 #ifndef NO_PRAGMA_ONCE
8 #pragma once
9 #endif
10 
11 #include "cBitArray.h"
16 
17 namespace GrayLib
18 {
20 
22  {
30 
31  typedef cBitArray SUPER_t;
32  typedef cBigUnsigned THIS_t;
33 
34  public:
36  {
38  }
40  : SUPER_t(x)
41  {
43  }
44 
45  cBigUnsigned(BIT_ENUM_t nBits, BLOCK_t uValMask) // Creates a cBigUnsigned with a capacity; for internal use.
46  : SUPER_t(nBits, uValMask)
47  {}
48 
49  cBigUnsigned(BLOCK_ENUM_t nBlocks, const BLOCK_t* pBlocks)
50  : SUPER_t(nBlocks, pBlocks)
51  {
53  }
54  cBigUnsigned(BLOCK_ENUM_t nBlocks, const BLOCK_t* pBlocks, bool bStatic)
55  : SUPER_t(nBlocks, pBlocks, bStatic)
56  {
58  ASSERT(bStatic);
59  }
60 
61  explicit cBigUnsigned(const char* pszStr, RADIX_t nBaseRadix = 10)
62  {
64  SetStr(pszStr, nBaseRadix);
65  }
66 
68  {
70  }
71 
72  // Constructors from primitive integer types. "cTypes.tbl"
73  cBigUnsigned(UINTMAX_t x) { put_ValU(x); }
74  cBigUnsigned(INTMAX_t x) { put_ValS(x); }
75 #if 1 // Stupid C++ compiler wont pick the correct one.
76  cBigUnsigned(UINT32 x) { put_ValU(x); }
77  cBigUnsigned(INT32 x) { put_ValS(x); }
78 #endif
79 
80  void SetBlockSizeInit(BLOCK_ENUM_t nBlocks, const BLOCK_t* pBlocks);
81 
82  bool isZero() const
83  {
86  return get_BlocksUse() == 0;
87  }
88  bool isOdd() const
89  {
91  if (isZero()) // 0 is not odd.
92  return false;
93  return(GetBlockInt(0) & 1);
94  }
95 
96  template <typename TYPE /*= BLOCK_t*/ >
97  TYPE get_ValU() const
98  {
101  size_t nSizeAvail = get_BlocksCap() * sizeof(BLOCK_t);
102  if (nSizeAvail <= 0)
103  {
104  return 0;
105  }
106  if (nSizeAvail < sizeof(TYPE))
107  {
108  TYPE uVal = 0;
109  ::memcpy(&uVal, get_BlockPtrC(), nSizeAvail);
110  return uVal;
111  }
112  // Its big enough. just cast it and return.
113  return(*((const TYPE*)get_BlockPtrC()));
114  }
115 
116  template <typename TYPE /*= BLOCK_t*/>
117  TYPE get_ValUC() const
118  {
120  BIT_ENUM_t nBits = get_Highest1Bit();
121  size_t nBytes = cBits::GetSizeBytes(nBits);
122  if (sizeof(TYPE) < nBytes)
123  {
124  ReturnError(DISP_E_OVERFLOW, "cBigUnsigned::get_ValS: Value is too big to fit in the requested type");
125  return 0;
126  }
127  return get_ValU<TYPE>();
128  }
129  template <typename TYPE /*= BLOCK_t*/>
130  TYPE get_ValS() const
131  {
133  TYPE uVal = get_ValUC<TYPE>();
134  if (uVal < 0) // Not enough room to hold the sign.
135  {
136  ReturnError(DISP_E_OVERFLOW, "cBigUnsigned::get_ValS: Value is too big to fit in the requested signed type");
137  return 0;
138  }
139  return uVal;
140  }
141  template <typename TYPE /*= BLOCK_t*/>
142  TYPE get_Val() const
143  {
145  return get_ValUC<TYPE>();
146  }
147 
149  COMPARE_t CompareU(BLOCK_t x) const;
150  bool operator == (BLOCK_t x) const { return CompareU(x) == COMPARE_Equal; }
151  bool operator != (BLOCK_t x) const { return CompareU(x) != COMPARE_Equal; }
152  bool operator < (BLOCK_t x) const { return CompareU(x) < 0; }
153  bool operator <= (BLOCK_t x) const { return CompareU(x) <= COMPARE_Equal; }
154  bool operator >= (BLOCK_t x) const { return CompareU(x) >= COMPARE_Equal; }
155  bool operator > (BLOCK_t x) const { return CompareU(x) > 0; }
156 
158  COMPARE_t Compare(const cBigUnsigned& x) const;
159  bool operator == (const cBigUnsigned& x) const { return IsEqual(x); }
160  bool operator != (const cBigUnsigned& x) const { return !IsEqual(x); }
161  bool operator < (const cBigUnsigned& x) const { return Compare(x) < 0; }
162  bool operator <= (const cBigUnsigned& x) const { return Compare(x) <= COMPARE_Equal; }
163  bool operator >= (const cBigUnsigned& x) const { return Compare(x) >= COMPARE_Equal; }
164  bool operator > (const cBigUnsigned& x) const { return Compare(x) > 0; }
165 
166  StrLen_t GetStr(char* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix = 10) const;
167  cString GetStr(RADIX_t nBaseRadix = 10) const;
168  bool SetStr(const char* pszVal, RADIX_t nBaseRadix = 10, const char** ppszEnd = (const char**) nullptr);
169 
170  //*************************************************
171  // Modifiers.
172 
173  void put_ValU(UINTMAX_t n);
174  HRESULT put_ValS(INTMAX_t n);
175 
176  template <typename TYPE>
177  void put_Val(TYPE n)
178  {
180  return put_ValU(n);
181  }
182 
183  void InitBitAnd(const cBigUnsigned& a, const cBigUnsigned& b);
184  void InitBitOr(const cBigUnsigned& a, const cBigUnsigned& b);
185  void InitBitXor(const cBigUnsigned& a, const cBigUnsigned& b);
186 
187  HRESULT InitBitShiftLeft(const cBigUnsigned& a, int b);
188  HRESULT InitBitShiftRight(const cBigUnsigned& a, int b);
189 
190  void OpBitShiftLeft1(BLOCK_t nBitMask = 0);
192  {
194  return InitBitShiftLeft(*this, b);
195  }
197  {
199  return InitBitShiftRight(*this, b);
200  }
201 
202  // Arguments are read-only operands, result is saved in *this.
203  void OpAdd1(BLOCK_t nVal);
204  HRESULT OpSubtract1(BLOCK_t nVal);
205  void InitSubtract1(const THIS_t& a, BLOCK_t n)
206  {
207  if (this != &a)
208  SetCopyBits(a);
209  OpSubtract1(n);
210  }
211 
212  void InitAdd(const cBigUnsigned& a, const cBigUnsigned& b);
213  HRESULT InitSubtract(const cBigUnsigned& a, const cBigUnsigned& b);
215  {
216  return InitSubtract(*this, b);
217  }
218 
219  static void MultiplyHelper(BLOCK_t* pDst, BLOCK_ENUM_t nBlocks, const cBigUnsigned& rSrc, BLOCK_t nMult);
220  void InitMultiply1(const cBigUnsigned& a, BLOCK_t b);
221  void InitMultiplyH(const cBigUnsigned& a, BLOCKH_t b);
222  void InitMultiply(const cBigUnsigned& a, const cBigUnsigned& b);
223 
224  BLOCK_t GetModulusH(BLOCKH_t b) const;
225  BLOCKH_t InitDivideH(const cBigUnsigned& a, BLOCKH_t b);
226  HRESULT InitDivide(const cBigUnsigned& a, const cBigUnsigned& b, OUT cBigUnsigned& remainder);
227  HRESULT InitDivide(const THIS_t& a, const THIS_t& b)
228  {
230  cBigUnsigned rJunkRemainder;
231  return InitDivide(a, b, rJunkRemainder);
232  }
233  HRESULT InitModulus(const THIS_t& a, const THIS_t& b)
234  {
236  cBigUnsigned rJunkQuotient;
237  return rJunkQuotient.InitDivide(a, b, *this);
238  }
239 
240  static void GRAYCALL EuclideanAlgorithm(const cBigUnsigned& x, const cBigUnsigned& y, OUT cBigUnsigned& a, OUT cBigUnsigned& b, OUT cBigUnsigned& g);
241  static cBigUnsigned GRAYCALL GetGreatestCommonDivisor(const cBigUnsigned& x, const cBigUnsigned& y);
242  HRESULT InitModInv(const cBigUnsigned& A, const cBigUnsigned& N);
243 
244  HRESULT SetRandomBits2(BIT_ENUM_t nBits, IRandomNoise* pRandom = nullptr);
245  HRESULT SetRandomBits(BIT_ENUM_t nBits, IRandomNoise* pRandom = nullptr);
246 
247  BLOCK_t get_MontgomeryInit() const;
248  void SetMontMul(THIS_t& rDst, const THIS_t& B, const THIS_t& N, BLOCK_t mm);
249  void SetMontRedux(THIS_t& rDst, const THIS_t& N, BLOCK_t mm);
250 
251  void SetPower(const THIS_t& base, const THIS_t& exponent);
252  HRESULT SetPowerMod(const THIS_t& base, const THIS_t& exponent, const THIS_t& modulus, OUT THIS_t* pRR = nullptr);
253 
254  BITOP_TYPE TestPrimeSmall() const;
255  HRESULT TestPrimeMiller(IRandomNoise* pRandom = nullptr) const;
256  HRESULT TestPrimeFermat(IRandomNoise* pRandom = nullptr) const;
257  HRESULT TestPrime(IRandomNoise* pRandom = nullptr) const;
258 
259  HRESULT SetPrimePrev(IRandomNoise* pRandom = nullptr, cThreadState* pCancel = nullptr);
260  HRESULT SetPrimeBits(BIT_ENUM_t nBits, IRandomNoise* pRandom = nullptr, cThreadState* pCancel = nullptr);
261  HRESULT SetPrimeBitsDH(BIT_ENUM_t nbits, IRandomNoise* pRandom = nullptr, cThreadState* pCancel = nullptr);
262 
265  {
266  cBigUnsigned ans;
267  ans.InitAdd(*this, x);
268  return ans;
269  }
271  {
272  cBigUnsigned ans(*this);
273  ans.OpAdd1(x);
274  return ans;
275  }
276  cBigUnsigned operator -(const THIS_t& x) const
277  {
278  cBigUnsigned ans;
279  ans.InitSubtract(*this, x);
280  return ans;
281  }
282  cBigUnsigned operator -(BLOCK_t x) const
283  {
284  cBigUnsigned ans(*this);
285  ans.OpSubtract1(x);
286  return ans;
287  }
289  {
290  cBigUnsigned ans;
291  ans.InitMultiply(*this, x);
292  return ans;
293  }
295  {
296  cBigUnsigned ans;
297  ans.InitMultiplyH(*this, x);
298  return ans;
299  }
300  cBigUnsigned operator /(const THIS_t& x) const
301  {
302  cBigUnsigned q;
303  q.InitDivide(*this, x);
304  return q;
305  }
306  cBigUnsigned operator /(BLOCKH_t n) const
307  {
308  cBigUnsigned q;
309  (void)q.InitDivideH(*this, n);
310  return q;
311  }
312  cBigUnsigned operator %(const THIS_t& x) const
313  {
315  cBigUnsigned r;
316  r.InitModulus(*this, x);
317  return r;
318  }
319  BLOCKH_t operator %(BLOCKH_t n) const
320  {
322  cBigUnsigned qJunk; // junk this.
323  return qJunk.InitDivideH(*this, n);
324  }
325 
326  // NOTE: NO unary minus allowed
328  {
329  cBigUnsigned ans;
330  ans.InitBitAnd(*this, x);
331  return ans;
332  }
334  {
335  cBigUnsigned ans;
336  ans.InitBitOr(*this, x);
337  return ans;
338  }
340  {
341  cBigUnsigned ans;
342  ans.InitBitXor(*this, x);
343  return ans;
344  }
346  {
347  cBigUnsigned ans;
348  ans.InitBitShiftLeft(*this, b);
349  return ans;
350  }
352  {
353  cBigUnsigned ans;
354  ans.InitBitShiftRight(*this, b);
355  return ans;
356  }
357 
358  // Overloaded assignment operators
359  void operator +=(const THIS_t& x)
360  {
361  InitAdd(*this, x);
362  }
363  void operator +=(BLOCK_t x)
364  {
365  OpAdd1(x);
366  }
367  void operator -=(const THIS_t& x)
368  {
369  InitSubtract(*this, x);
370  }
371  void operator -= (BLOCK_t x)
372  {
373  OpSubtract1(x);
374  }
375  void operator *= (const THIS_t& x)
376  {
377  InitMultiply(*this, x);
378  }
379  void operator *= (BLOCKH_t x)
380  {
381  InitMultiplyH(*this, x);
382  }
383 
384  void operator /= (const THIS_t& x)
385  {
387  cBigUnsigned d = *this;
388  InitDivide(d, x);
389  }
390  void operator /= (BLOCKH_t n)
391  {
392  (void)InitDivideH(*this, n);
393  }
394  inline void operator %=(const THIS_t& x)
395  {
397  cBigUnsigned d = *this;
398  InitModulus(d, x);
399  }
400  void operator %= (BLOCKH_t n)
401  {
402  // use *this as intermediate value as well.
403  put_ValU(InitDivideH(*this, n));
404  }
405  void operator &=(const THIS_t& x)
406  {
407  InitBitAnd(*this, x);
408  }
409  void operator |=(const THIS_t& x)
410  {
411  InitBitOr(*this, x);
412  }
413  void operator ^=(const THIS_t& x)
414  {
415  InitBitXor(*this, x);
416  }
417  void operator <<=(int b)
418  {
419  OpBitShiftLeft(b);
420  }
421  void operator >>=(int b)
422  {
423  OpBitShiftRight(b);
424  }
425 
426  // Increment/Decrement operators
427  // To discourage messy coding, these do not return *this, so prefix and postfix behave the same.
428  void operator ++()
429  {
430  OpAdd1(1);
431  }
432  void operator ++(int)
433  {
435  OpAdd1(1);
436  }
437  void operator --()
438  {
439  OpSubtract1(1);
440  }
441  void operator --(int)
442  {
444  OpSubtract1(1);
445  }
446 
448  };
449 
451 #ifdef USE_INT64
452  template <> inline INT64 cBigUnsigned::get_Val() const
453  {
454  return get_ValS<INT64>();
455  }
456 #endif
457 #ifndef USE_LONG_AS_INT64
458  template <> inline long cBigUnsigned::get_Val() const
459  {
460  return get_ValS<long>();
461  }
462 #endif
463  template <> inline int cBigUnsigned::get_Val() const
464  {
465  return get_ValS<int>();
466  }
467  template <> inline short cBigUnsigned::get_Val() const
468  {
469  return get_ValS<short>();
470  }
471 
472 #ifdef USE_INT64
473  template <> inline void cBigUnsigned::put_Val(INT64 n)
474  {
475  put_ValS(n);
476  }
477 #endif
478 #ifndef USE_LONG_AS_INT64
479  template <> inline void cBigUnsigned::put_Val(long n)
480  {
481  put_ValS(n);
482  }
483 #endif
484  template <> inline void cBigUnsigned::put_Val(int n)
485  {
486  put_ValS(n);
487  }
488  template <> inline void cBigUnsigned::put_Val(short n)
489  {
490  put_ValS(n);
491  }
492 };
493 #endif
#define GRAYCALL
declare calling convention for static functions so everyone knows the arg passing scheme....
Definition: GrayCore.h:36
#define GRAYLIB_LINK
Definition: GrayLibBase.h:35
Using X files without the sources and the makefile How to use you just create a debug directory e g
Definition: Readme.txt:21
#define TYPE
Definition: StrT.cpp:38
UINT64 UINTMAX_t
Definition: SysTypes.h:435
INT64 INTMAX_t
Definition: SysTypes.h:434
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
#define ASSERT(exp)
Definition: cDebugAssert.h:87
Definition: cBigUnsigned.h:22
TYPE get_Val() const
Definition: cBigUnsigned.h:142
HRESULT InitDivide(const cBigUnsigned &a, const cBigUnsigned &b, OUT cBigUnsigned &remainder)
Definition: cBigUnsMulDiv.cpp:1078
bool isOdd() const
Definition: cBigUnsigned.h:88
cBigUnsigned(INT32 x)
Definition: cBigUnsigned.h:77
HRESULT InitBitShiftLeft(const cBigUnsigned &a, int b)
Definition: cBigUnsigned.cpp:325
HRESULT OpSubtract1(BLOCK_t nVal)
Definition: cBigUnsigned.cpp:485
void InitSubtract1(const THIS_t &a, BLOCK_t n)
Definition: cBigUnsigned.h:205
cBigUnsigned(BLOCK_ENUM_t nBlocks, const BLOCK_t *pBlocks)
Definition: cBigUnsigned.h:49
HRESULT InitSubtract(const cBigUnsigned &a, const cBigUnsigned &b)
Definition: cBigUnsigned.cpp:589
TYPE get_ValUC() const
Definition: cBigUnsigned.h:117
void InitBitAnd(const cBigUnsigned &a, const cBigUnsigned &b)
Definition: cBigUnsigned.cpp:223
cBigUnsigned(UINTMAX_t x)
Definition: cBigUnsigned.h:73
cBigUnsigned(INTMAX_t x)
Definition: cBigUnsigned.h:74
cBigUnsigned(const char *pszStr, RADIX_t nBaseRadix=10)
Definition: cBigUnsigned.h:61
HRESULT InitDivide(const THIS_t &a, const THIS_t &b)
Definition: cBigUnsigned.h:227
cBigUnsigned(const cBigUnsigned &x)
Definition: cBigUnsigned.h:39
cBigUnsigned()
Definition: cBigUnsigned.h:35
void InitBitOr(const cBigUnsigned &a, const cBigUnsigned &b)
Definition: cBigUnsigned.cpp:240
HRESULT OpBitShiftLeft(BIT_ENUM_t b)
Definition: cBigUnsigned.h:191
cBigUnsigned(BIT_ENUM_t nBits, BLOCK_t uValMask)
Definition: cBigUnsigned.h:45
cBigUnsigned(UINT32 x)
Definition: cBigUnsigned.h:76
void InitMultiplyH(const cBigUnsigned &a, BLOCKH_t b)
Definition: cBigUnsMulDiv.cpp:972
TYPE get_ValS() const
Definition: cBigUnsigned.h:130
BLOCKH_t InitDivideH(const cBigUnsigned &a, BLOCKH_t b)
Definition: cBigUnsMulDiv.cpp:1046
HRESULT InitBitShiftRight(const cBigUnsigned &a, int b)
Definition: cBigUnsigned.cpp:401
HRESULT put_ValS(INTMAX_t n)
Definition: cBigUnsigned.cpp:211
HRESULT OpBitShiftRight(BIT_ENUM_t b)
Definition: cBigUnsigned.h:196
void InitMultiply(const cBigUnsigned &a, const cBigUnsigned &b)
Definition: cBigUnsMulDiv.cpp:911
cBigUnsigned(BLOCK_ENUM_t nBlocks, const BLOCK_t *pBlocks, bool bStatic)
Definition: cBigUnsigned.h:54
UNITTEST_FRIEND(cBigUnsigned)
void InitAdd(const cBigUnsigned &a, const cBigUnsigned &b)
Definition: cBigUnsigned.cpp:510
bool isZero() const
Definition: cBigUnsigned.h:82
HRESULT OpSubtract(const THIS_t &b)
Definition: cBigUnsigned.h:214
void OpAdd1(BLOCK_t nVal)
Definition: cBigUnsigned.cpp:465
HRESULT InitModulus(const THIS_t &a, const THIS_t &b)
Definition: cBigUnsigned.h:233
~cBigUnsigned()
Definition: cBigUnsigned.h:67
TYPE get_ValU() const
Definition: cBigUnsigned.h:97
void put_Val(TYPE n)
Definition: cBigUnsigned.h:177
void InitBitXor(const cBigUnsigned &a, const cBigUnsigned &b)
Definition: cBigUnsigned.cpp:274
unsigned int BLOCK_ENUM_t
Type for the index of a BLOCK_t in the array. NOT bits BIT_ENUM_t.
Definition: cBitArray.h:78
UINT32 BLOCK_t
The biggest unsigned type I can do atomic math on for this architecture.
Definition: cBitArray.h:46
WORD BLOCKH_t
half sized BLOCK_t for multiplication overflows.
Definition: cBitArray.h:48
Definition: cBitArray.h:416
Definition: cThreadLock.h:137
Definition: cMesh.h:22
cVecT2< TYPE > operator*(const TYPE nVal, const cVecT2< TYPE > &v2)
Definition: cVecT.h:522
UNITTEST2_PREDEF(cQuadtree)
cUInt64 operator|(const cUInt64 &roUI64_1, const cUInt64 &roUI64_2)
Definition: cUInt64.h:377
int COMPARE_t
result of compare. 0=same, 1=a>b, -1=a<b
Definition: cValT.h:17
BITOP_TYPE
Definition: cBits.h:22
int StrLen_t
the length of a string in chars (bytes for UTF8, wchar_t for UNICODE). or offset in characters....
Definition: StrConst.h:32
void operator>>(cArchive &ar, cStringT< _TYPE_CH > &pOb)
Definition: cString.h:678
cUInt64 operator^(const cUInt64 &roUI64_1, const cUInt64 &roUI64_2)
Definition: cUInt64.h:391
WORD RADIX_t
Base for convert of numbers to strings. e.g. 10 base vs 16 base hex numbers.
Definition: StrChar.h:27
unsigned int BIT_ENUM_t
Enumerate number of bits or address a single bit in some array of bits.
Definition: cBits.h:20
bool operator<(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:234
bool operator>=(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:246
cStringA operator+(const char *pStr1, const cStringA &s2)
Definition: cString.h:642
void operator<<(cArchive &ar, const cStringT< _TYPE_CH > &pOb)
Definition: cString.h:680
bool operator!=(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:254
bool operator==(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:250
bool operator>(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:242
@ COMPARE_Equal
VARCMP_EQ.
Definition: cValT.h:23
bool operator<=(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:238
cUInt64 operator&(const cUInt64 &roUI64_1, const cUInt64 &roUI64_2)
Definition: cUInt64.h:384
Definition: cRandom.h:19
static constexpr size_t GetSizeBytes(BIT_ENUM_t nBits) noexcept
Definition: cBits.h:54