BrianGladman / mpir

Multiple Precision Integers and Rationals
GNU General Public License v3.0
75 stars 36 forks source link

Porting to AHK - Please provide example DLL usage. #23

Open Qriist opened 2 years ago

Qriist commented 2 years ago

Hello, thank you for your impressive work. I had no issues building the Visual Studio x64 Release DLL. (dll_mpir_gc)

While not entirely unfamiliar with c/c++ concepts, I am not particularly fluent in using them. Therein lies the problem.

I'm trying to wrap a few functions for use in AHK and I have to admit I'm a little mystified by the custom typedef declarations, such as mpf_t. I've been banging my head for several hours. (It looks like they might just be byte arrays? I have some experience making structs and would be willing to craft whatever's required on AHK's side if you could point me at the right place in the code.)

Anyways, I respectfully request some example C++ code utilizing the DLL version. I guess I need mpf_init_set, mpf_add, & mpf_div specifically.

I... think... I can figure the rest out from there.

Thanks in advance. I know it's a lot to randomly ask.

BrianGladman commented 2 years ago

MPIR itself is written in C and this means that its types are defined in C. To use it from C++ you can either wrap the functions you need in a C++ wrapper that you build yourself (as I can see you intend to do) or you can use the already supplied C++ interface defined in the header file mpirxx.h. Using the supplied C++ header will be much easier for you since it will relieve you of the hard work of allocating, initialising and releasing memory for the MPIR types that you want to use, leaving you to focus on your application without worrying about the details.

However if you wish to build your own C++ wrapper, you can look at mpirxx.h to see how your can write code to wrap the basic C types that MPIR provides. You should not need to worry about the internal details of the types since these are all handled by the functions that MPIR provides.

While mpirxx.h has an adequate interface to MPIR, if you intend to use both multiple length reals in your application, you might also wish to consider using MPIR with MPFR since the latter provides 'state of the art' multiple length reals. This would allow you to use the MPFRC++ interface (see: http://www.holoborodko.com/pavel/mpfr/) for both MPIR and MPFR. This would then provide you with multiple length integers and reals in your application where you can just treat them as you would treat ordinary integers and doubles without having to worry about all the details of how these types are implemented.

I use MPIR and MPFR extensively to build C++ applications and my approach is to use the MPFRC++ wrapper.

SanderBouwhuis commented 2 years ago

Here is the header of the wrapper I wrote. This should help you get started on your own wrapper.

//
// CBigInt.h : Definitions file for CBigInt.cpp
//
//

// Only include this header file once
#pragma once

#include "_Export.h"

// Check whether to export this class or not
#ifdef CBIGINT
  #ifdef CLASSES_DLL
    #define CBIGINT_EXP __declspec(dllexport)
  #else
    #define CBIGINT_EXP __declspec(dllimport)
  #endif
#else
  #define CBIGINT_EXP
#endif

// Include some headers
#include "Mpir.h"

// Forward declaration
class CWString;

// The CBigInt class
class CBIGINT_EXP CBigInt
{
  // Allow access to private variables and functions
  friend class CBigFloat;

private:
  // Variables
  mpz_t m_mpz;  // The big integer

  // Function prototypes
  bool IsPrime_Lookup(uint32 u32Number) const;
  bool IsPrime_MillerRabin(uint8 u8TotTests = 8) const;

public:
  // Constructors
           CBigInt()                                  { mpz_init(m_mpz); }
           CBigInt(const CBigInt &biNum)              { mpz_init(m_mpz); mpz_set(m_mpz, biNum.m_mpz); }
  explicit CBigInt(const CBigInt *pbiNum)             { mpz_init(m_mpz); if(pbiNum) mpz_set(m_mpz, pbiNum->m_mpz); }
  explicit CBigInt(double dNum);
  explicit CBigInt(int8 i8Num)                        { mpz_init(m_mpz); mpz_set_sx(m_mpz, i8Num); }
  explicit CBigInt(uint8 u8Num)                       { mpz_init(m_mpz); mpz_set_ux(m_mpz, u8Num); }
  explicit CBigInt(int16 i16Num)                      { mpz_init(m_mpz); mpz_set_sx(m_mpz, i16Num); }
  explicit CBigInt(uint16 u16Num)                     { mpz_init(m_mpz); mpz_set_ux(m_mpz, u16Num); }
  explicit CBigInt(int32 i32Num)                      { mpz_init(m_mpz); mpz_set_sx(m_mpz, i32Num); }
  explicit CBigInt(uint32 u32Num)                     { mpz_init(m_mpz); mpz_set_ux(m_mpz, u32Num); }
  explicit CBigInt(long lNum)                         { mpz_init(m_mpz); mpz_set_sx(m_mpz, lNum); }
  explicit CBigInt(unsigned long ulNum)               { mpz_init(m_mpz); mpz_set_ux(m_mpz, ulNum); }
  explicit CBigInt(int64 i64Num)                      { mpz_init(m_mpz); mpz_set_sx(m_mpz, i64Num); }
  explicit CBigInt(uint64 u64Num)                     { mpz_init(m_mpz); mpz_set_ux(m_mpz, u64Num); }
  explicit CBigInt(const char *pcNum, uint8 u8Base = 10);
  explicit CBigInt(const wchar_t *pwcNum, uint8 u8Base = 10);
          ~CBigInt()                                  { mpz_clear(m_mpz); }

  // Casting overloads
  explicit operator double() const                    { return mpz_get_d(m_mpz); }
  explicit operator int8() const                      { return int8(mpz_get_sx(m_mpz) & 0xff); }
  explicit operator uint8() const                     { return uint8(mpz_get_ux(m_mpz) & 0xff); }
  explicit operator int16() const                     { return int16(mpz_get_sx(m_mpz) & 0xffff); }
  explicit operator uint16() const                    { return uint16(mpz_get_ux(m_mpz) & 0xffff); }
  explicit operator int32() const                     { return int32(mpz_get_sx(m_mpz) & 0xffffffff); }
  explicit operator uint32() const                    { return uint32(mpz_get_ux(m_mpz) & 0xffffffff); }
  explicit operator int64() const                     { return int64(mpz_get_sx(m_mpz)); }
  explicit operator uint64() const                    { return uint64(mpz_get_ux(m_mpz)); }

  // Assignment operators
  CBigInt& operator = (const CBigInt &biNum)          { mpz_set(m_mpz, biNum.m_mpz);           return *this; }
  CBigInt& operator = (double dNum)                   { mpz_set(m_mpz, CBigInt(dNum).m_mpz);   return *this; }
  CBigInt& operator = (int8 i8Num)                    { mpz_set(m_mpz, CBigInt(i8Num).m_mpz);  return *this; }
  CBigInt& operator = (uint8 u8Num)                   { mpz_set(m_mpz, CBigInt(u8Num).m_mpz);  return *this; }
  CBigInt& operator = (int16 i16Num)                  { mpz_set(m_mpz, CBigInt(i16Num).m_mpz); return *this; }
  CBigInt& operator = (uint16 u16Num)                 { mpz_set(m_mpz, CBigInt(u16Num).m_mpz); return *this; }
  CBigInt& operator = (int32 i32Num)                  { mpz_set(m_mpz, CBigInt(i32Num).m_mpz); return *this; }
  CBigInt& operator = (uint32 u32Num)                 { mpz_set(m_mpz, CBigInt(u32Num).m_mpz); return *this; }
  CBigInt& operator = (int64 i64Num)                  { mpz_set(m_mpz, CBigInt(i64Num).m_mpz); return *this; }
  CBigInt& operator = (uint64 u64Num)                 { mpz_set(m_mpz, CBigInt(u64Num).m_mpz); return *this; }
  CBigInt& operator = (const char *pcNum)             { mpz_set(m_mpz, CBigInt(pcNum).m_mpz);  return *this; }
  CBigInt& operator = (const wchar_t *pwcNum)         { mpz_set(m_mpz, CBigInt(pwcNum).m_mpz); return *this; }

  // Arithmetic assignment operators
  CBigInt& operator -= (const CBigInt &biNum)         { mpz_sub(m_mpz, m_mpz, biNum.m_mpz);           return *this; }
  CBigInt& operator -= (double dNum)                  { mpz_sub(m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return *this; }
  CBigInt& operator -= (int8 i8Num)                   { mpz_sub(m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return *this; }
  CBigInt& operator -= (uint8 u8Num)                  { mpz_sub(m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return *this; }
  CBigInt& operator -= (int16 i16Num)                 { mpz_sub(m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return *this; }
  CBigInt& operator -= (uint16 u16Num)                { mpz_sub(m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return *this; }
  CBigInt& operator -= (int32 i32Num)                 { mpz_sub(m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return *this; }
  CBigInt& operator -= (uint32 u32Num)                { mpz_sub(m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return *this; }
  CBigInt& operator -= (int64 i64Num)                 { mpz_sub(m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return *this; }
  CBigInt& operator -= (uint64 u64Num)                { mpz_sub(m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return *this; }
  CBigInt& operator -= (const char *pcNum)            { mpz_sub(m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return *this; }
  CBigInt& operator -= (const wchar_t *pwcNum)        { mpz_sub(m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return *this; }

  CBigInt& operator += (const CBigInt &biNum)         { mpz_add(m_mpz, m_mpz, biNum.m_mpz);           return *this; }
  CBigInt& operator += (double dNum)                  { mpz_add(m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return *this; }
  CBigInt& operator += (int8 i8Num)                   { mpz_add(m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return *this; }
  CBigInt& operator += (uint8 u8Num)                  { mpz_add(m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return *this; }
  CBigInt& operator += (int16 i16Num)                 { mpz_add(m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return *this; }
  CBigInt& operator += (uint16 u16Num)                { mpz_add(m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return *this; }
  CBigInt& operator += (int32 i32Num)                 { mpz_add(m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return *this; }
  CBigInt& operator += (uint32 u32Num)                { mpz_add(m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return *this; }
  CBigInt& operator += (int64 i64Num)                 { mpz_add(m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return *this; }
  CBigInt& operator += (uint64 u64Num)                { mpz_add(m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return *this; }
  CBigInt& operator += (const char *pcNum)            { mpz_add(m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return *this; }
  CBigInt& operator += (const wchar_t *pwcNum)        { mpz_add(m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return *this; }

  CBigInt& operator *= (const CBigInt &biNum)         { mpz_mul(m_mpz, m_mpz, biNum.m_mpz);           return *this; }
  CBigInt& operator *= (double dNum)                  { mpz_mul(m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return *this; }
  CBigInt& operator *= (int8 i8Num)                   { mpz_mul(m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return *this; }
  CBigInt& operator *= (uint8 u8Num)                  { mpz_mul(m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return *this; }
  CBigInt& operator *= (int16 i16Num)                 { mpz_mul(m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return *this; }
  CBigInt& operator *= (uint16 u16Num)                { mpz_mul(m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return *this; }
  CBigInt& operator *= (int32 i32Num)                 { mpz_mul(m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return *this; }
  CBigInt& operator *= (uint32 u32Num)                { mpz_mul(m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return *this; }
  CBigInt& operator *= (int64 i64Num)                 { mpz_mul(m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return *this; }
  CBigInt& operator *= (uint64 u64Num)                { mpz_mul(m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return *this; }
  CBigInt& operator *= (const char *pcNum)            { mpz_mul(m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return *this; }
  CBigInt& operator *= (const wchar_t *pwcNum)        { mpz_mul(m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return *this; }

  CBigInt& operator /= (const CBigInt &biNum)         { mpz_div(m_mpz, m_mpz, biNum.m_mpz);           return *this; }
  CBigInt& operator /= (double dNum)                  { mpz_div(m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return *this; }
  CBigInt& operator /= (int8 i8Num)                   { mpz_div(m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return *this; }
  CBigInt& operator /= (uint8 u8Num)                  { mpz_div(m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return *this; }
  CBigInt& operator /= (int16 i16Num)                 { mpz_div(m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return *this; }
  CBigInt& operator /= (uint16 u16Num)                { mpz_div(m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return *this; }
  CBigInt& operator /= (int32 i32Num)                 { mpz_div(m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return *this; }
  CBigInt& operator /= (uint32 u32Num)                { mpz_div(m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return *this; }
  CBigInt& operator /= (int64 i64Num)                 { mpz_div(m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return *this; }
  CBigInt& operator /= (uint64 u64Num)                { mpz_div(m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return *this; }
  CBigInt& operator /= (const char *pcNum)            { mpz_div(m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return *this; }
  CBigInt& operator /= (const wchar_t *pwcNum)        { mpz_div(m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return *this; }

  CBigInt& operator %= (const CBigInt &biNum)         { mpz_mod(m_mpz, m_mpz, biNum.m_mpz);           return *this; }
  CBigInt& operator %= (double dNum)                  { mpz_mod(m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return *this; }
  CBigInt& operator %= (int8 i8Num)                   { mpz_mod(m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return *this; }
  CBigInt& operator %= (uint8 u8Num)                  { mpz_mod(m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return *this; }
  CBigInt& operator %= (int16 i16Num)                 { mpz_mod(m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return *this; }
  CBigInt& operator %= (uint16 u16Num)                { mpz_mod(m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return *this; }
  CBigInt& operator %= (int32 i32Num)                 { mpz_mod(m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return *this; }
  CBigInt& operator %= (uint32 u32Num)                { mpz_mod(m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return *this; }
  CBigInt& operator %= (int64 i64Num)                 { mpz_mod(m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return *this; }
  CBigInt& operator %= (uint64 u64Num)                { mpz_mod(m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return *this; }
  CBigInt& operator %= (const char *pcNum)            { mpz_mod(m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return *this; }
  CBigInt& operator %= (const wchar_t *pwcNum)        { mpz_mod(m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return *this; }

  // Unary minus
  CBigInt operator- () const                          { CBigInt biTemp; mpz_neg(biTemp.m_mpz, m_mpz); return biTemp; }

  // Function prototypes (arithmetic operators)
  CBigInt operator - (const CBigInt &biNum) const     { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, biNum.m_mpz);           return biTemp; }
  CBigInt operator - (double dNum) const              { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return biTemp; }
  CBigInt operator - (int8 i8Num) const               { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return biTemp; }
  CBigInt operator - (uint8 u8Num) const              { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return biTemp; }
  CBigInt operator - (int16 i16Num) const             { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return biTemp; }
  CBigInt operator - (uint16 u16Num) const            { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return biTemp; }
  CBigInt operator - (int32 i32Num) const             { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return biTemp; }
  CBigInt operator - (uint32 u32Num) const            { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return biTemp; }
  CBigInt operator - (int64 i64Num) const             { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return biTemp; }
  CBigInt operator - (uint64 u64Num) const            { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return biTemp; }
  CBigInt operator - (const char *pcNum) const        { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return biTemp; }
  CBigInt operator - (const wchar_t *pwcNum) const    { CBigInt biTemp; mpz_sub(biTemp.m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return biTemp; }

  CBigInt operator + (const CBigInt &biNum) const     { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, biNum.m_mpz);           return biTemp; }
  CBigInt operator + (double dNum) const              { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return biTemp; }
  CBigInt operator + (int8 i8Num) const               { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return biTemp; }
  CBigInt operator + (uint8 u8Num) const              { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return biTemp; }
  CBigInt operator + (int16 i16Num) const             { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return biTemp; }
  CBigInt operator + (uint16 u16Num) const            { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return biTemp; }
  CBigInt operator + (int32 i32Num) const             { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return biTemp; }
  CBigInt operator + (uint32 u32Num) const            { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return biTemp; }
  CBigInt operator + (int64 i64Num) const             { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return biTemp; }
  CBigInt operator + (uint64 u64Num) const            { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return biTemp; }
  CBigInt operator + (const char *pcNum) const        { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return biTemp; }
  CBigInt operator + (const wchar_t *pwcNum) const    { CBigInt biTemp; mpz_add(biTemp.m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return biTemp; }

  CBigInt operator * (const CBigInt &biNum) const     { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, biNum.m_mpz);           return biTemp; }
  CBigInt operator * (double dNum) const              { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return biTemp; }
  CBigInt operator * (int8 i8Num) const               { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return biTemp; }
  CBigInt operator * (uint8 u8Num) const              { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return biTemp; }
  CBigInt operator * (int16 i16Num) const             { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return biTemp; }
  CBigInt operator * (uint16 u16Num) const            { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return biTemp; }
  CBigInt operator * (int32 i32Num) const             { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return biTemp; }
  CBigInt operator * (uint32 u32Num) const            { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return biTemp; }
  CBigInt operator * (int64 i64Num) const             { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return biTemp; }
  CBigInt operator * (uint64 u64Num) const            { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return biTemp; }
  CBigInt operator * (const char *pcNum) const        { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return biTemp; }
  CBigInt operator * (const wchar_t *pwcNum) const    { CBigInt biTemp; mpz_mul(biTemp.m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return biTemp; }

  CBigInt operator / (const CBigInt &biNum) const     { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, biNum.m_mpz);           return biTemp; }
  CBigInt operator / (double dNum) const              { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return biTemp; }
  CBigInt operator / (int8 i8Num) const               { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return biTemp; }
  CBigInt operator / (uint8 u8Num) const              { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return biTemp; }
  CBigInt operator / (int16 i16Num) const             { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return biTemp; }
  CBigInt operator / (uint16 u16Num) const            { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return biTemp; }
  CBigInt operator / (int32 i32Num) const             { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return biTemp; }
  CBigInt operator / (uint32 u32Num) const            { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return biTemp; }
  CBigInt operator / (int64 i64Num) const             { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return biTemp; }
  CBigInt operator / (uint64 u64Num) const            { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return biTemp; }
  CBigInt operator / (const char *pcNum) const        { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return biTemp; }
  CBigInt operator / (const wchar_t *pwcNum) const    { CBigInt biTemp; mpz_div(biTemp.m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return biTemp; }

  CBigInt operator % (const CBigInt &biNum) const     { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, biNum.m_mpz);           return biTemp; }
  CBigInt operator % (double dNum) const              { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(dNum).m_mpz);   return biTemp; }
  CBigInt operator % (int8 i8Num) const               { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return biTemp; }
  CBigInt operator % (uint8 u8Num) const              { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return biTemp; }
  CBigInt operator % (int16 i16Num) const             { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return biTemp; }
  CBigInt operator % (uint16 u16Num) const            { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return biTemp; }
  CBigInt operator % (int32 i32Num) const             { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return biTemp; }
  CBigInt operator % (uint32 u32Num) const            { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return biTemp; }
  CBigInt operator % (int64 i64Num) const             { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return biTemp; }
  CBigInt operator % (uint64 u64Num) const            { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return biTemp; }
  CBigInt operator % (const char *pcNum) const        { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return biTemp; }
  CBigInt operator % (const wchar_t *pwcNum) const    { CBigInt biTemp; mpz_mod(biTemp.m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return biTemp; }

  // Increment and decrement operators
  CBigInt& operator -- ()                             { mpz_sub_ui(m_mpz, m_mpz, 1); return *this; }
  CBigInt  operator -- (int32)                        { CBigInt biTemp(*this); mpz_sub_ui(m_mpz, m_mpz, 1); return biTemp; }
  CBigInt& operator ++ ()                             { mpz_add_ui(m_mpz, m_mpz, 1); return *this; }
  CBigInt  operator ++ (int32)                        { CBigInt biTemp(*this); mpz_add_ui(m_mpz, m_mpz, 1); return biTemp; }

  // Comparison operators
  bool operator < (const CBigInt &biNum) const        { return mpz_cmp(m_mpz, biNum.m_mpz) < 0; }
  bool operator < (double dNum) const                 { return mpz_cmp(m_mpz, CBigInt(dNum).m_mpz)   < 0; }
  bool operator < (int8 i8Num) const                  { return mpz_cmp(m_mpz, CBigInt(i8Num).m_mpz)  < 0; }
  bool operator < (uint8 u8Num) const                 { return mpz_cmp(m_mpz, CBigInt(u8Num).m_mpz)  < 0; }
  bool operator < (int16 i16Num) const                { return mpz_cmp(m_mpz, CBigInt(i16Num).m_mpz) < 0; }
  bool operator < (uint16 u16Num) const               { return mpz_cmp(m_mpz, CBigInt(u16Num).m_mpz) < 0; }
  bool operator < (int32 i32Num) const                { return mpz_cmp(m_mpz, CBigInt(i32Num).m_mpz) < 0; }
  bool operator < (uint32 u32Num) const               { return mpz_cmp(m_mpz, CBigInt(u32Num).m_mpz) < 0; }
  bool operator < (int64 i64Num) const                { return mpz_cmp(m_mpz, CBigInt(i64Num).m_mpz) < 0; }
  bool operator < (uint64 u64Num) const               { return mpz_cmp(m_mpz, CBigInt(u64Num).m_mpz) < 0; }
  bool operator < (const char *pcNum) const           { return mpz_cmp(m_mpz, CBigInt(pcNum).m_mpz)  < 0; }
  bool operator < (const wchar_t *pwcNum) const       { return mpz_cmp(m_mpz, CBigInt(pwcNum).m_mpz) < 0; }

  bool operator <= (const CBigInt &biNum) const       { return mpz_cmp(m_mpz, biNum.m_mpz) <= 0; }
  bool operator <= (double dNum) const                { return mpz_cmp(m_mpz, CBigInt(dNum).m_mpz)   <= 0; }
  bool operator <= (int8 i8Num) const                 { return mpz_cmp(m_mpz, CBigInt(i8Num).m_mpz)  <= 0; }
  bool operator <= (uint8 u8Num) const                { return mpz_cmp(m_mpz, CBigInt(u8Num).m_mpz)  <= 0; }
  bool operator <= (int16 i16Num) const               { return mpz_cmp(m_mpz, CBigInt(i16Num).m_mpz) <= 0; }
  bool operator <= (uint16 u16Num) const              { return mpz_cmp(m_mpz, CBigInt(u16Num).m_mpz) <= 0; }
  bool operator <= (int32 i32Num) const               { return mpz_cmp(m_mpz, CBigInt(i32Num).m_mpz) <= 0; }
  bool operator <= (uint32 u32Num) const              { return mpz_cmp(m_mpz, CBigInt(u32Num).m_mpz) <= 0; }
  bool operator <= (int64 i64Num) const               { return mpz_cmp(m_mpz, CBigInt(i64Num).m_mpz) <= 0; }
  bool operator <= (uint64 u64Num) const              { return mpz_cmp(m_mpz, CBigInt(u64Num).m_mpz) <= 0; }
  bool operator <= (const char *pcNum) const          { return mpz_cmp(m_mpz, CBigInt(pcNum).m_mpz)  <= 0; }
  bool operator <= (const wchar_t *pwcNum) const      { return mpz_cmp(m_mpz, CBigInt(pwcNum).m_mpz) <= 0; }

  bool operator == (const CBigInt &biNum) const       { return mpz_cmp(m_mpz, biNum.m_mpz) == 0; }
  bool operator == (double dNum) const                { return mpz_cmp(m_mpz, CBigInt(dNum).m_mpz)   == 0; }
  bool operator == (int8 i8Num) const                 { return mpz_cmp(m_mpz, CBigInt(i8Num).m_mpz)  == 0; }
  bool operator == (uint8 u8Num) const                { return mpz_cmp(m_mpz, CBigInt(u8Num).m_mpz)  == 0; }
  bool operator == (int16 i16Num) const               { return mpz_cmp(m_mpz, CBigInt(i16Num).m_mpz) == 0; }
  bool operator == (uint16 u16Num) const              { return mpz_cmp(m_mpz, CBigInt(u16Num).m_mpz) == 0; }
  bool operator == (int32 i32Num) const               { return mpz_cmp(m_mpz, CBigInt(i32Num).m_mpz) == 0; }
  bool operator == (uint32 u32Num) const              { return mpz_cmp(m_mpz, CBigInt(u32Num).m_mpz) == 0; }
  bool operator == (int64 i64Num) const               { return mpz_cmp(m_mpz, CBigInt(i64Num).m_mpz) == 0; }
  bool operator == (uint64 u64Num) const              { return mpz_cmp(m_mpz, CBigInt(u64Num).m_mpz) == 0; }
  bool operator == (const char *pcNum) const          { return mpz_cmp(m_mpz, CBigInt(pcNum).m_mpz)  == 0; }
  bool operator == (const wchar_t *pwcNum) const      { return mpz_cmp(m_mpz, CBigInt(pwcNum).m_mpz) == 0; }

  bool operator >= (const CBigInt &biNum) const       { return mpz_cmp(m_mpz, biNum.m_mpz) >= 0; }
  bool operator >= (double dNum) const                { return mpz_cmp(m_mpz, CBigInt(dNum).m_mpz)   >= 0; }
  bool operator >= (int8 i8Num) const                 { return mpz_cmp(m_mpz, CBigInt(i8Num).m_mpz)  >= 0; }
  bool operator >= (uint8 u8Num) const                { return mpz_cmp(m_mpz, CBigInt(u8Num).m_mpz)  >= 0; }
  bool operator >= (int16 i16Num) const               { return mpz_cmp(m_mpz, CBigInt(i16Num).m_mpz) >= 0; }
  bool operator >= (uint16 u16Num) const              { return mpz_cmp(m_mpz, CBigInt(u16Num).m_mpz) >= 0; }
  bool operator >= (int32 i32Num) const               { return mpz_cmp(m_mpz, CBigInt(i32Num).m_mpz) >= 0; }
  bool operator >= (uint32 u32Num) const              { return mpz_cmp(m_mpz, CBigInt(u32Num).m_mpz) >= 0; }
  bool operator >= (int64 i64Num) const               { return mpz_cmp(m_mpz, CBigInt(i64Num).m_mpz) >= 0; }
  bool operator >= (uint64 u64Num) const              { return mpz_cmp(m_mpz, CBigInt(u64Num).m_mpz) >= 0; }
  bool operator >= (const char *pcNum) const          { return mpz_cmp(m_mpz, CBigInt(pcNum).m_mpz)  >= 0; }
  bool operator >= (const wchar_t *pwcNum) const      { return mpz_cmp(m_mpz, CBigInt(pwcNum).m_mpz) >= 0; }

  bool operator > (const CBigInt &biNum) const        { return mpz_cmp(m_mpz, biNum.m_mpz) > 0; }
  bool operator > (double dNum) const                 { return mpz_cmp(m_mpz, CBigInt(dNum).m_mpz)   > 0; }
  bool operator > (int8 i8Num) const                  { return mpz_cmp(m_mpz, CBigInt(i8Num).m_mpz)  > 0; }
  bool operator > (uint8 u8Num) const                 { return mpz_cmp(m_mpz, CBigInt(u8Num).m_mpz)  > 0; }
  bool operator > (int16 i16Num) const                { return mpz_cmp(m_mpz, CBigInt(i16Num).m_mpz) > 0; }
  bool operator > (uint16 u16Num) const               { return mpz_cmp(m_mpz, CBigInt(u16Num).m_mpz) > 0; }
  bool operator > (int32 i32Num) const                { return mpz_cmp(m_mpz, CBigInt(i32Num).m_mpz) > 0; }
  bool operator > (uint32 u32Num) const               { return mpz_cmp(m_mpz, CBigInt(u32Num).m_mpz) > 0; }
  bool operator > (int64 i64Num) const                { return mpz_cmp(m_mpz, CBigInt(i64Num).m_mpz) > 0; }
  bool operator > (uint64 u64Num) const               { return mpz_cmp(m_mpz, CBigInt(u64Num).m_mpz) > 0; }
  bool operator > (const char *pcNum) const           { return mpz_cmp(m_mpz, CBigInt(pcNum).m_mpz)  > 0; }
  bool operator > (const wchar_t *pwcNum) const       { return mpz_cmp(m_mpz, CBigInt(pwcNum).m_mpz) > 0; }

  bool operator ! ()                                  { return mpz_cmp_ui(m_mpz, 0) == 0; }

  bool operator != (const CBigInt &biNum) const       { return mpz_cmp(m_mpz, biNum.m_mpz) != 0; }
  bool operator != (int8 i8Num) const                 { return mpz_cmp(m_mpz, CBigInt(i8Num).m_mpz)  != 0; }
  bool operator != (uint8 u8Num) const                { return mpz_cmp(m_mpz, CBigInt(u8Num).m_mpz)  != 0; }
  bool operator != (int16 i16Num) const               { return mpz_cmp(m_mpz, CBigInt(i16Num).m_mpz) != 0; }
  bool operator != (uint16 u16Num) const              { return mpz_cmp(m_mpz, CBigInt(u16Num).m_mpz) != 0; }
  bool operator != (int32 i32Num) const               { return mpz_cmp(m_mpz, CBigInt(i32Num).m_mpz) != 0; }
  bool operator != (uint32 u32Num) const              { return mpz_cmp(m_mpz, CBigInt(u32Num).m_mpz) != 0; }
  bool operator != (int64 i64Num) const               { return mpz_cmp(m_mpz, CBigInt(i64Num).m_mpz) != 0; }
  bool operator != (uint64 u64Num) const              { return mpz_cmp(m_mpz, CBigInt(u64Num).m_mpz) != 0; }
  bool operator != (const char *pcNum) const          { return mpz_cmp(m_mpz, CBigInt(pcNum).m_mpz)  != 0; }
  bool operator != (const wchar_t *pwcNum) const      { return mpz_cmp(m_mpz, CBigInt(pwcNum).m_mpz) != 0; }

  // Bitwise operators
  CBigInt operator & (const CBigInt &biNum) const     { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, biNum.m_mpz);           return biTemp; }
  CBigInt operator & (int8 i8Num) const               { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return biTemp; }
  CBigInt operator & (uint8 u8Num) const              { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return biTemp; }
  CBigInt operator & (int16 i16Num) const             { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return biTemp; }
  CBigInt operator & (uint16 u16Num) const            { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return biTemp; }
  CBigInt operator & (int32 i32Num) const             { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return biTemp; }
  CBigInt operator & (uint32 u32Num) const            { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return biTemp; }
  CBigInt operator & (int64 i64Num) const             { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return biTemp; }
  CBigInt operator & (uint64 u64Num) const            { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return biTemp; }
  CBigInt operator & (const char *pcNum) const        { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return biTemp; }
  CBigInt operator & (const wchar_t *pwcNum) const    { CBigInt biTemp; mpz_and(biTemp.m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return biTemp; }

  CBigInt& operator &= (const CBigInt &biNum)         { mpz_and(m_mpz, m_mpz, biNum.m_mpz);           return *this; }
  CBigInt& operator &= (int8 i8Num)                   { mpz_and(m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return *this; }
  CBigInt& operator &= (uint8 u8Num)                  { mpz_and(m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return *this; }
  CBigInt& operator &= (int16 i16Num)                 { mpz_and(m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return *this; }
  CBigInt& operator &= (uint16 u16Num)                { mpz_and(m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return *this; }
  CBigInt& operator &= (int32 i32Num)                 { mpz_and(m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return *this; }
  CBigInt& operator &= (uint32 u32Num)                { mpz_and(m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return *this; }
  CBigInt& operator &= (int64 i64Num)                 { mpz_and(m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return *this; }
  CBigInt& operator &= (uint64 u64Num)                { mpz_and(m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return *this; }
  CBigInt& operator &= (const char *pcNum)            { mpz_and(m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return *this; }
  CBigInt& operator &= (const wchar_t *pwcNum)        { mpz_and(m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return *this; }

  CBigInt operator | (const CBigInt &biNum) const     { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, biNum.m_mpz);           return biTemp; }
  CBigInt operator | (int8 i8Num) const               { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return biTemp; }
  CBigInt operator | (uint8 u8Num) const              { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return biTemp; }
  CBigInt operator | (int16 i16Num) const             { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return biTemp; }
  CBigInt operator | (uint16 u16Num) const            { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return biTemp; }
  CBigInt operator | (int32 i32Num) const             { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return biTemp; }
  CBigInt operator | (uint32 u32Num) const            { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return biTemp; }
  CBigInt operator | (int64 i64Num) const             { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return biTemp; }
  CBigInt operator | (uint64 u64Num) const            { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return biTemp; }
  CBigInt operator | (const char *pcNum) const        { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return biTemp; }
  CBigInt operator | (const wchar_t *pwcNum) const    { CBigInt biTemp; mpz_ior(biTemp.m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return biTemp; }

  CBigInt& operator |= (const CBigInt &biNum)         { mpz_ior(m_mpz, m_mpz, biNum.m_mpz);           return *this; }
  CBigInt& operator |= (int8 i8Num)                   { mpz_ior(m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return *this; }
  CBigInt& operator |= (uint8 u8Num)                  { mpz_ior(m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return *this; }
  CBigInt& operator |= (int16 i16Num)                 { mpz_ior(m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return *this; }
  CBigInt& operator |= (uint16 u16Num)                { mpz_ior(m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return *this; }
  CBigInt& operator |= (int32 i32Num)                 { mpz_ior(m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return *this; }
  CBigInt& operator |= (uint32 u32Num)                { mpz_ior(m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return *this; }
  CBigInt& operator |= (int64 i64Num)                 { mpz_ior(m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return *this; }
  CBigInt& operator |= (uint64 u64Num)                { mpz_ior(m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return *this; }
  CBigInt& operator |= (const char *pcNum)            { mpz_ior(m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return *this; }
  CBigInt& operator |= (const wchar_t *pwcNum)        { mpz_ior(m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return *this; }

  CBigInt operator ^ (const CBigInt &biNum) const     { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, biNum.m_mpz); return biTemp; }
  CBigInt operator ^ (int8 i8Num) const               { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return biTemp; }
  CBigInt operator ^ (uint8 u8Num) const              { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return biTemp; }
  CBigInt operator ^ (int16 i16Num) const             { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return biTemp; }
  CBigInt operator ^ (uint16 u16Num) const            { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return biTemp; }
  CBigInt operator ^ (int32 i32Num) const             { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return biTemp; }
  CBigInt operator ^ (uint32 u32Num) const            { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return biTemp; }
  CBigInt operator ^ (int64 i64Num) const             { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return biTemp; }
  CBigInt operator ^ (uint64 u64Num) const            { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return biTemp; }
  CBigInt operator ^ (const char *pcNum) const        { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return biTemp; }
  CBigInt operator ^ (const wchar_t *pwcNum) const    { CBigInt biTemp; mpz_xor(biTemp.m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return biTemp; }

  CBigInt& operator ^= (const CBigInt &biNum)         { mpz_xor(m_mpz, m_mpz, biNum.m_mpz);           return *this; }
  CBigInt& operator ^= (int8 i8Num)                   { mpz_xor(m_mpz, m_mpz, CBigInt(i8Num).m_mpz);  return *this; }
  CBigInt& operator ^= (uint8 u8Num)                  { mpz_xor(m_mpz, m_mpz, CBigInt(u8Num).m_mpz);  return *this; }
  CBigInt& operator ^= (int16 i16Num)                 { mpz_xor(m_mpz, m_mpz, CBigInt(i16Num).m_mpz); return *this; }
  CBigInt& operator ^= (uint16 u16Num)                { mpz_xor(m_mpz, m_mpz, CBigInt(u16Num).m_mpz); return *this; }
  CBigInt& operator ^= (int32 i32Num)                 { mpz_xor(m_mpz, m_mpz, CBigInt(i32Num).m_mpz); return *this; }
  CBigInt& operator ^= (uint32 u32Num)                { mpz_xor(m_mpz, m_mpz, CBigInt(u32Num).m_mpz); return *this; }
  CBigInt& operator ^= (int64 i64Num)                 { mpz_xor(m_mpz, m_mpz, CBigInt(i64Num).m_mpz); return *this; }
  CBigInt& operator ^= (uint64 u64Num)                { mpz_xor(m_mpz, m_mpz, CBigInt(u64Num).m_mpz); return *this; }
  CBigInt& operator ^= (const char *pcNum)            { mpz_xor(m_mpz, m_mpz, CBigInt(pcNum).m_mpz);  return *this; }
  CBigInt& operator ^= (const wchar_t *pwcNum)        { mpz_xor(m_mpz, m_mpz, CBigInt(pwcNum).m_mpz); return *this; }

  CBigInt operator ~ () const                         { CBigInt biTemp; mpz_com(biTemp.m_mpz, m_mpz); return biTemp; }

  CBigInt operator << (const CBigInt &biNum) const    { CBigInt biTemp; mpz_mul_2exp(biTemp.m_mpz, m_mpz, mpz_get_ui(biNum.m_mpz)); return biTemp; }
  CBigInt operator << (int8 i8Num) const              { CBigInt biTemp; mpz_mul_2exp(biTemp.m_mpz, m_mpz, i8Num);                   return biTemp; }
  CBigInt operator << (uint8 u8Num) const             { CBigInt biTemp; mpz_mul_2exp(biTemp.m_mpz, m_mpz, u8Num);                   return biTemp; }
  CBigInt operator << (int16 i16Num) const            { CBigInt biTemp; mpz_mul_2exp(biTemp.m_mpz, m_mpz, i16Num);                  return biTemp; }
  CBigInt operator << (uint16 u16Num) const           { CBigInt biTemp; mpz_mul_2exp(biTemp.m_mpz, m_mpz, u16Num);                  return biTemp; }
  CBigInt operator << (int32 i32Num) const            { CBigInt biTemp; mpz_mul_2exp(biTemp.m_mpz, m_mpz, i32Num);                  return biTemp; }
  CBigInt operator << (uint32 u32Num) const           { CBigInt biTemp; mpz_mul_2exp(biTemp.m_mpz, m_mpz, u32Num);                  return biTemp; }

  CBigInt& operator <<= (const CBigInt &biNum)        { mpz_mul_2exp(m_mpz, m_mpz, mpz_get_ui(biNum.m_mpz)); return *this; }
  CBigInt& operator <<= (int8 i8Num)                  { mpz_mul_2exp(m_mpz, m_mpz, i8Num);                   return *this; }
  CBigInt& operator <<= (uint8 u8Num)                 { mpz_mul_2exp(m_mpz, m_mpz, u8Num);                   return *this; }
  CBigInt& operator <<= (int16 i16Num)                { mpz_mul_2exp(m_mpz, m_mpz, i16Num);                  return *this; }
  CBigInt& operator <<= (uint16 u16Num)               { mpz_mul_2exp(m_mpz, m_mpz, u16Num);                  return *this; }
  CBigInt& operator <<= (int32 i32Num)                { mpz_mul_2exp(m_mpz, m_mpz, i32Num);                  return *this; }
  CBigInt& operator <<= (uint32 u32Num)               { mpz_mul_2exp(m_mpz, m_mpz, u32Num);                  return *this; }

  CBigInt operator >> (const CBigInt &biNum) const    { CBigInt biTemp; mpz_fdiv_q_2exp(biTemp.m_mpz, m_mpz, mpz_get_ui(biNum.m_mpz)); return biTemp; }
  CBigInt operator >> (int8 i8Num) const              { CBigInt biTemp; mpz_fdiv_q_2exp(biTemp.m_mpz, m_mpz, i8Num);                   return biTemp; }
  CBigInt operator >> (uint8 u8Num) const             { CBigInt biTemp; mpz_fdiv_q_2exp(biTemp.m_mpz, m_mpz, u8Num);                   return biTemp; }
  CBigInt operator >> (int16 i16Num) const            { CBigInt biTemp; mpz_fdiv_q_2exp(biTemp.m_mpz, m_mpz, i16Num);                  return biTemp; }
  CBigInt operator >> (uint16 u16Num) const           { CBigInt biTemp; mpz_fdiv_q_2exp(biTemp.m_mpz, m_mpz, u16Num);                  return biTemp; }
  CBigInt operator >> (int32 i32Num) const            { CBigInt biTemp; mpz_fdiv_q_2exp(biTemp.m_mpz, m_mpz, i32Num);                  return biTemp; }
  CBigInt operator >> (uint32 u32Num) const           { CBigInt biTemp; mpz_fdiv_q_2exp(biTemp.m_mpz, m_mpz, u32Num);                  return biTemp; }

  CBigInt& operator >>= (const CBigInt &biNum)        { mpz_fdiv_q_2exp(m_mpz, m_mpz, mpz_get_ui(biNum.m_mpz)); return *this; }
  CBigInt& operator >>= (int8 i8Num)                  { mpz_fdiv_q_2exp(m_mpz, m_mpz, i8Num);                   return *this; }
  CBigInt& operator >>= (uint8 u8Num)                 { mpz_fdiv_q_2exp(m_mpz, m_mpz, u8Num);                   return *this; }
  CBigInt& operator >>= (int16 i16Num)                { mpz_fdiv_q_2exp(m_mpz, m_mpz, i16Num);                  return *this; }
  CBigInt& operator >>= (uint16 u16Num)               { mpz_fdiv_q_2exp(m_mpz, m_mpz, u16Num);                  return *this; }
  CBigInt& operator >>= (int32 i32Num)                { mpz_fdiv_q_2exp(m_mpz, m_mpz, i32Num);                  return *this; }
  CBigInt& operator >>= (uint32 u32Num)               { mpz_fdiv_q_2exp(m_mpz, m_mpz, u32Num);                  return *this; }

  // Function prototypes
            CBigInt       GetAbs() const                                                                 { CBigInt biTemp; mpz_abs(biTemp.m_mpz, m_mpz); return biTemp; }//CBigInt biTemp(this); biTemp.SetAbs(); return biTemp; }
            CBigInt       GetFactorial() const                                                           { CBigInt biTemp; mpz_fac_ui(biTemp.m_mpz, uint32(biTemp)); return biTemp; }
            CBigInt       GetGCD(const CBigInt &biNum) const                                             { CBigInt biTemp; mpz_gcd(biTemp.m_mpz, m_mpz, biNum.m_mpz); return biTemp; }
            CBigInt       GetGCD(const CBigInt &biNumA, const CBigInt &biNumB) const                     { CBigInt biTemp; mpz_gcd(biTemp.m_mpz, biNumA.m_mpz, biNumB.m_mpz); return biTemp; }
            CBigInt       GetPower(uint32 u32Exponent) const                                             { CBigInt biTemp; mpz_pow_ui(biTemp.m_mpz, m_mpz, u32Exponent); return biTemp; }
            CBigInt       GetPower(CBigInt biBase, uint32 u32Exponent) const                             { CBigInt biTemp; mpz_pow_ui(biTemp.m_mpz, biBase.m_mpz, u32Exponent); return biTemp; }
            CBigInt       GetPowerThenModulus(CBigInt biBase, CBigInt biExponent, CBigInt biMod) const   { CBigInt biTemp; mpz_powm(biTemp.m_mpz, biBase.m_mpz, biExponent.m_mpz, biMod.m_mpz); return biTemp; }
            CBigInt       GetPrime_GetNextPrime(const CBigInt &biStartValue, uint8 u8TotTests = 8) const { CBigInt biTemp(this); biTemp.SetPrime_GetNextPrime(biStartValue, u8TotTests); return biTemp; }
            CBigInt       GetPrime_GetPrevPrime(const CBigInt &biStartValue, uint8 u8TotTests = 8) const { CBigInt biTemp(this); biTemp.SetPrime_GetPrevPrime(biStartValue, u8TotTests); return biTemp; }
            CBigInt       SetPrime_GetRandomPrime(const CBigInt &biMinValue, const CBigInt &biMaxValue, uint8 u8TotTests = 8) const { CBigInt biTemp(this); biTemp.SetPrime_GetRandomPrime(biMinValue, biMaxValue, u8TotTests); return biTemp; }
            CBigInt       GetRandomNumber(const CBigInt &biMin, const CBigInt &biMax) const;
            uint32        GetTotDigits(uint8 u8Base) const                                               { return uint32(mpz_sizeinbase(m_mpz, u8Base)); }
            bool          IsEven() const                                                                 { return mpz_even_p(m_mpz) != 0; }
            bool          IsOdd() const                                                                  { return mpz_odd_p(m_mpz) != 0; }
            bool          IsPrime(uint8 u8TotTests = 8) const;
            bool          IsPrime_DiffieHellmanSafe(uint8 u8TotTests = 8) const;
            CBigInt&      SetAbs()                                                                       { mpz_abs(m_mpz, m_mpz); return *this; }
            CBigInt&      SetFactorial()                                                                 { mpz_fac_ui(m_mpz, uint32(*this)); return *this; }
            CBigInt&      SetFactorial(uint32 u32Factorial)                                              { mpz_fac_ui(m_mpz, u32Factorial); return *this; }
            CBigInt&      SetGCD(const CBigInt &biNum)                                                   { mpz_gcd(m_mpz, biNum.m_mpz, m_mpz); return *this; }
            CBigInt&      SetGCD(const CBigInt &biNumA, const CBigInt &biNumB)                           { mpz_gcd(m_mpz, biNumA.m_mpz, biNumB.m_mpz); return *this; }
            CBigInt&      SetPower(uint32 u32Exponent)                                                   { mpz_pow_ui(m_mpz, m_mpz, u32Exponent); return *this; }
            CBigInt&      SetPower(CBigInt biBase, uint32 u32Exponent)                                   { mpz_pow_ui(m_mpz, biBase.m_mpz, u32Exponent); return *this; }
            CBigInt&      SetPowerThenModulus(CBigInt biBase, CBigInt biExponent, CBigInt biMod)         { mpz_powm(m_mpz, biBase.m_mpz, biExponent.m_mpz, biMod.m_mpz); return *this; }
            CBigInt&      SetPowerThenModulus(CBigInt biBase, uint32 u32Exponent, CBigInt biMod)         { mpz_powm_ui(m_mpz, biBase.m_mpz, u32Exponent, biMod.m_mpz); return *this; }
            CBigInt&      SetPrime_GetNextPrime(const CBigInt &biStartValue, uint8 u8TotTests = 8);
            CBigInt&      SetPrime_GetPrevPrime(const CBigInt &biStartValue, uint8 u8TotTests = 8);
            CBigInt&      SetPrime_GetRandomPrime(const CBigInt &biMinValue, const CBigInt &biMaxValue, uint8 u8TotTests = 8);
            CBigInt&      SetRandomNumber(const CBigInt &biMin, const CBigInt &biMax)                    { *this = GetRandomNumber(biMin, biMax); return *this; }
            CWString      ToString(uint8 u8Base = 10) const;
  constexpr char*         ToString(char *pcNum, uint32 u32MaxChars, uint8 u8Base = 10, uint32 *pu32Len = nullptr) const;
  constexpr wchar_t*      ToString(wchar_t *pwcNum, uint32 u32MaxChars, uint8 u8Base = 10, uint32 *pu32Len = nullptr) const;
  constexpr std::wstring* ToString(std::wstring *pWstrBigInt) const;
};
Qriist commented 2 years ago

Sorry for the late reply. Holy moly those are both really helpful comments! I will definitely be digging into everything you guys suggested. Thanks!