/* * "BigInteger Class" * * * Arbitrary Precision Integer¸¦ ¸ñÇ¥·Î ¸¸µé¾ú½À´Ï´Ù. * ±×·¯³ª Perfect Arbitrary¿¡´Â ¹ÌÄ¡Áö ¸øÇß½À´Ï´Ù. * ÃÖ´ë 10^4,294,967,301±îÁö »ý¼º, Ãâ·Â °¡´ÉÇÕ´Ï´Ù. * À̰ͺ¸´Ù ´õ ³ôÀº ¼ýÀÚ´Â ¸¸µé ¼ö ¾ø½À´Ï´Ù. * * * #include * #include "BigInteger.h" * using namespace std; * * int main() * { * BigInteger a(123); * cout << a * a * a * a * a * a * a << endl; * // 425927596977747 * } * * * À§¿Í °°ÀÌ ±âº» Á¤¼öÇü°ú »ç¿ë¹ýÀÌ ¶È°°½À´Ï´Ù. * * intÇüÀÌ Áö¿øÇÏ´Â ¸ðµç ¿¬»êÀÚ¸¦ Áö¿øÇÕ´Ï´Ù.(ºñÆ®¿¬»ê, ½¬ÇÁÆ®¿¬»ê, »çÄ¢¿¬»ê...) * Ãß°¡ÀûÀ¸·Î BigIntgerÇüÀº ¹®ÀÚ¿­·ÎºÎÅÍ ÃʱâÈ­°¡ °¡´ÉÇÕ´Ï´Ù. * 2~36Áø¹ýÀÇ ¹®ÀÚ¿­·ÎºÎÅÍ ÃʱâÈ­ ÇÒ ¼ö ÀÖ½À´Ï´Ù. * ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÕ´Ï´Ù. * * BigInteger a("123", 16); * * 16Áø¹ý 123À¸·Î ÃʱâÈ­ µÇ¸ç ÀÌ´Â 10Áø¹ýÀ¸·Î 291ÀÌ µË´Ï´Ù. * * * * ÀÌ Å¬·¡½º´Â ÈÄ¿¡, Arbitrary Precision Decimal¸¦ ¸¸µé±â À§ÇÑ Åä´ë°¡ µÉ °ÍÀÔ´Ï´Ù. * Ŭ·¡½º¸¦ óÀ½À¸·Î ¹èÆ÷ÇÑ ³¯Â¥´Â 2011³â 7¿ù 14ÀÏÀ̸ç * ÀÌ Å¬·¡½º¿¡ ´ëÇÑ Ãß°¡¼³¸í ¹× ¹èÆ÷´Â Á¦ °³ÀÎ ºí·Î±× * http://transparenttape.tistory.com/ * ¿¡¼­ °è¼Ó ÇÒ °ÍÀÔ´Ï´Ù. * BigInteger¸¦ ¸¸µé±â À§ÇØ ÀÌ ÀڷḦ º¸½Ã´Â °Å¶ó¸é * Á¦ ºí·Î±×¿¡ ºÎ¿¬¼³¸í ±ÛÀ» ¿Ã·ÈÀ¸´Ï Âü°íÇϽñ⠹ٶø´Ï´Ù. * * Ȥ½Ã Á¦°¡ ¸¸µç ¶óÀ̺귯¸®¸¦ »ç¿ëÇϸ鼭 * ¿À·ù, ¹ö±×¸¦ ¹ß°ßÇϼ̴ٸé Áöü¾øÀÌ À§ÀÇ ºí·Î±×¿¡ ±ÛÀ» ³²°ÜÁֽðųª * ghwjd111@naver.com ȤÀº ghwjd111@gmail.comÀ¸·Î ¸ÞÀÏÀ» º¸³»ÁÖ½Å´Ù¸é °¨»çÇÏ°Ú½À´Ï´Ù. ^^ * * * */ #pragma once #ifndef _BIGINTEGER_H_ #define _BIGINTEGER_H_ #include #include #include class BigInteger; typedef BigInteger bigint; class BigInteger { /* * ¹è¿­À» »ç¿ëÇÏ¿© ¼ýÀÚ¸¦ ÀúÀå * little endian, 2Áø¹ýÀ» »ç¿ë * * ÇϳªÀÇ BigIntegerÇüÀº * ¼ýÀÚ¸¦ ÀúÀåÇÏ´Â µ¿Àû ¹è¿­, * ¹è¿­ÀÇ ±æÀ̸¦ ÀúÀåÇÏ´Â unsigned longÇü º¯¼ö, * ºÎÈ£ * ·Î ÀÌ·ç¾îÁ®ÀÖ½À´Ï´Ù. */ public: /* * ŸÀÔ ¹× º¯¼ö * * --ŸÀÔ-- * * length : ±æÀÌ °ü·Ã ŸÀÔ, ÄÚµåÀÇ °¡µ¶¼ºÀ» ³ôÀÌ°íÀÚ ½èÀ¸¸ç * º°´Ù¸¥ ÀÌÀ¯´Â ¾ø½À´Ï´Ù. ÇÔ¼öÀÇ Àμö·Î ³Ñ¾î°¡°Å³ª ÇÔ¼ö ³» * Áö¿ªº¯¼ö »ç¿ë½Ã¿¡ ½±°Ô ÀÌÇØÇÒ ¼ö ÀÖ½À´Ï´Ù. * * index : ¹è¿­ÀÇ ¹øÈ£ °ü·Ã ŸÀÔ, À§¿Í ÀÌÀ¯´Â °°½À´Ï´Ù. * * blocktype : ¹è¿­ÀÇ Å¸ÀÔ, À§¿Í ÀÌÀ¯´Â °°½À´Ï´Ù. * * _sign : ºÎÈ£ ŸÀÔ, ¾ç¼ö¿Í À½¼ö ±×¸®°í 0À¸·Î ±¸¼ºµÇ¾îÀÖ½À´Ï´Ù. * * * --º¯¼ö-- * * blk : ½ÇÁúÀûÀ¸·Î ¼ýÀÚ°¡ ÀúÀåµÇ´Â µ¿Àû ¹è¿­ÀÔ´Ï´Ù. * * len : ¹è¿­ÀÇ ±æÀ̸¦ ÀúÀåÇÏ´Â º¯¼öÀÔ´Ï´Ù. * * sign : ¼ýÀÚÀÇ ºÎÈ£¸¦ ³ªÅ¸³½´Ù. */ typedef unsigned long length; // ±æÀÌ °ü·Ã ŸÀÔ typedef unsigned long index; // blkÀÇ ¹è¿­ ¹øÈ£ °ü·Ã ŸÀÔ typedef unsigned long blocktype; // blkÀÇ ¹è¿­ ŸÀÔ typedef enum { Positive = 1, Zero = 0, Negative = -1 } _sign; // ºÎÈ£, ¾ç¼ö, À½¼ö, ¿µÀ¸·Î ±¸¼º private: blocktype *blk; // ½ÇÁúÀûÀÎ ¼ýÀÚ ÀúÀå °ø°£ length len; // ¹è¿­ ±æÀÌ _sign sign; private: // ±æÀÌ c¸¸Å­ blk¸¦ ÇÒ´çÇÏ´Â ÇÔ¼öÀÔ´Ï´Ù. void Allocate(length c); // ±æÀÌ c¸¸Å­ ÀçÇÒ´çÇÏ´Â ÇÔ¼öÀÔ´Ï´Ù. // ¹«Á¶°Ç ±æÀÌ c¸¸Å­À¸·Î ÀçÇÒ´çÇϸç // blk¸¦ ÇØÁ¦ ÈÄ, Allocate ÇÔ¼ö¸¦ È£ÃâÇÕ´Ï´Ù. void Reallocate(length c); // blk¹è¿­ÀÇ ¸ðµç ¿ä¼Ò¸¦ 0À¸·Î ¸¸µì´Ï´Ù. inline void Blkinit(); // blk¹è¿­À» º¹»çÇÕ´Ï´Ù. inline void Blkcopy(const BigInteger &x); // 0À¸·Î ÃʱâÈ­Çϱâ À§ÇØ »ç¿ëÇÕ´Ï´Ù. inline void SetZero(); // blk¸¦ ÇØÁ¦ ÈÄ, 0À¸·Î ÃʱâÈ­ ÇÕ´Ï´Ù. inline void Reset(); /* * ¿¬»ê °úÁ¤¿¡¼­ blk°¡ ÇÒ´ç ÇÑ ¸¸Å­ Â÷Áö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. * ±×·± °æ¿ì zapLeadingZeros ÇÔ¼ö¸¦ È£ÃâÇÏ¿© * lenÀÇ ±æÀ̸¦ ÁÙÀÔ´Ï´Ù. */ inline void ZapLeadingZeros(); public: /* * ±âº» »ý¼ºÀÚ´Â 0À» ¸¸µå´Â °ÍÀ¸·Î Á¤ÀÇ * 0Àº ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ * len = 0 * blk = NULL * sign = Zero */ BigInteger(); ~BigInteger(); BigInteger(const BigInteger &x); // »ý¼º °¡´ÉÇÑ ¸ðµç ŸÀÔÀ¸·ÎºÎÅÍ ´ëÀÔÀÌ °¡´ÉÇÕ´Ï´Ù. BigInteger & operator =(const BigInteger &x); private: // ConversionAssist1Àº unsignedÀ¸·ÎºÎÅÍ »ý¼º½Ã »ç¿ë template void ConversionAssist1(PRI x); template <> void ConversionAssist1(unsigned long long x); // ConversionAssist2´Â signedÀ¸·ÎºÎÅÍ »ý¼º½Ã »ç¿ë template void ConversionAssist2(PRI x); template <> void ConversionAssist2(long long x); public: // boolÇü ¹× Á¤¼öÇüÀ¸·ÎºÎÅÍ »ý¼ºÀÌ °¡´ÉÇÕ´Ï´Ù. // float, doubleÇü¿¡¼­ÀÇ »ý¼ºÀº Áö¿øÇÏÁö ¾Ê½À´Ï´Ù. BigInteger( bool x); BigInteger(unsigned char x); BigInteger( char x); BigInteger(unsigned short x); BigInteger( short x); BigInteger(unsigned long x); BigInteger( long x); BigInteger(unsigned int x); BigInteger( int x); BigInteger(unsigned __int64 x); BigInteger( __int64 x); private: // ConversionAssist3Àº unsignedÀ¸·Î º¯È¯½Ã »ç¿ë template const PRI ConversionAssist3() const; template <> const unsigned long long ConversionAssist3() const; // ConversionAssist4Àº signedÀ¸·Î º¯È¯½Ã »ç¿ë template const PRI ConversionAssist4() const; template <> const long long ConversionAssist4() const; public: operator bool () const; operator unsigned char () const; operator char () const; operator unsigned short () const; operator short () const; operator unsigned long () const; operator long () const; operator unsigned int () const; operator int () const; operator unsigned __int64() const; operator __int64() const; private: void DoubleDabble(BigInteger &dest, int radix) const; void DD_Odd(BigInteger &dest, int radix) const; public: // char Çü ¹è¿­, stringÀ¸·Î ºÎÅÍ »ý¼º °¡´ÉÇÕ´Ï´Ù. explicit BigInteger(const char *str, int radix = 10); explicit BigInteger(const std::string &str, int radix = 10); // stringÀ» BigIntegerÇüÀ¸·Î ¹Ù²Ù´Â ÇÔ¼öÀÔ´Ï´Ù. const BigInteger & stob(const std::string &str, int radix = 10); // BigIntegerÇüÀ» stringÀ¸·Î ¹Ù²ß´Ï´Ù. const std::string btos(int radix = 10) const; // Ç¥ÁØ ÀÔ Ãâ·Â ÇÔ¼ö¸¦ ¿À¹ö·Îµù ÇÏ¿© // ÀÏ¹Ý Á¤¼öÇüó·³ ÀÔ Ãâ·Â ÇÒ ¼ö ÀÖ½À´Ï´Ù. // ´Ü, 10Áø¹ý¸¸À¸·Î ÀÔ·Â, Ãâ·ÂÇÕ´Ï´Ù. friend std::ostream & operator <<(std::ostream &os, const BigInteger &x); // ÀÓÀÇ Áø¹ýÀ¸·Î Ãâ·ÂÇÕ´Ï´Ù. void print(int radix = 10) const; friend std::istream & operator >>(std::istream &is, BigInteger &x); #pragma endregion #pragma endregion /* * ¿¬»êÀÇ ¼ø¼­µµ(this, x) * * 1. ÁÖ¼Ò°¡ °°Àº°¡ ´Ù¸¥°¡ ? * ¤¡. °°À» °æ¿ì - (ó¸®) * ¤¤. ´Ù¸¦ °æ¿ì - (´ÙÀ½À¸·Î) * 2. ºÎÈ£°¡ °°Àº°¡ ´Ù¸¥°¡ ? * ¤¡. Zero Á¸Àç * a. µÑ ´Ù 0 - (ó¸®) * b. this¸¸ 0 - (ó¸®) * c. x¸¸ 0 - (ó¸®) * ¤¤. µÎ °³ÀÇ ºÎÈ£°¡ ´Ù¸¦ °æ¿ì - (ó¸®) * ¤§. ºÎÈ£°¡ ¼­·Î °°À» °æ¿ì - (´ÙÀ½À¸·Î) * 3. ±æÀÌ°¡ °°Àº°¡ ´Ù¸¥°¡ ? * ¤¡. ´Ù¸¦ °æ¿ì - (ó¸®) * ¤¤. °°Àº °æ¿ì - (´ÙÀ½À¸·Î) * 4. ±× ¿Ü °æ¿ì ó¸® * * ¿¬»ê¿¡ µû¶ó¼­ * ÀϺδ »ý·« °¡´É ȤÀº ¹Ù²ð ¼ö ÀÖÀ½ */ #pragma region ºñ±³¿¬»ê public: const _sign getsign() const; // ºÎÈ£ ¸®ÅÏ // Å©±â¸¦ ºñ±³ÇÕ´Ï´Ù. const int compare(const BigInteger &x) const; // ºñ±³ ¿¬»êÀÚ ¿À¹ö·Îµù ÀÔ´Ï´Ù. // BigIntegerÇü°ú BigIntegerÇüÀÇ ºñ±³ // BigIntegerÇü°ú Á¤¼öÇüÀÇ ºñ±³.. µî // ÀÏ¹Ý Á¤¼öÇüó·³ »ç¿ë °¡´ÉÇÕ´Ï´Ù. bool operator ==(const BigInteger &x) const; bool operator !=(const BigInteger &x) const; bool operator > (const BigInteger &x) const; bool operator >=(const BigInteger &x) const; bool operator < (const BigInteger &x) const; bool operator <=(const BigInteger &x) const; template bool operator ==(const X &x) const; template bool operator !=(const X &x) const; template bool operator > (const X &x) const; template bool operator >=(const X &x) const; template bool operator < (const X &x) const; template bool operator <=(const X &x) const; template friend bool operator ==(const X &x, const BigInteger &y); template friend bool operator !=(const X &x, const BigInteger &y); template friend bool operator > (const X &x, const BigInteger &y); template friend bool operator >=(const X &x, const BigInteger &y); template friend bool operator < (const X &x, const BigInteger &y); template friend bool operator <=(const X &x, const BigInteger &y); #pragma endregion #pragma region ºñÆ®¿¬»ê public: unsigned __int64 bitlength() const; length blklength() const; /* * P : Positive * N : Negative * Z : Zero * * * a b || & | ^ * ------------------------------ * P P || P P P * P N || P N N * N P || P N N * N N || N N P * * '&' ¿¬»ê°ú '^' ¿¬»êÀº Z°¡ ³ª¿Ã °¡´É¼ºÀÌ ÀÖ½À´Ï´Ù. */ const BigInteger operator & (const BigInteger &x) const; const BigInteger & operator &=(const BigInteger &x); const BigInteger operator | (const BigInteger &x) const; const BigInteger & operator |=(const BigInteger &x); const BigInteger operator ^ (const BigInteger &x) const; const BigInteger & operator ^=(const BigInteger &x); const BigInteger operator ~ () const; template const BigInteger operator & (const X &x) const; template const BigInteger operator | (const X &x) const; template const BigInteger operator ^ (const X &x) const; template const BigInteger operator &=(const X &x); template const BigInteger operator |=(const X &x); template const BigInteger operator ^=(const X &x); template friend const BigInteger operator & (const X &x, const BigInteger &y); template friend const BigInteger operator | (const X &x, const BigInteger &y); template friend const BigInteger operator ^ (const X &x, const BigInteger &y); template friend const X & operator &=(X &x, const BigInteger &y); template friend const X & operator |=(X &x, const BigInteger &y); template friend const X & operator ^=(X &x, const BigInteger &y); #pragma endregion #pragma region ½¬ÇÁÆ®¿¬»ê private: // ºí·Ï ´ÜÀ§·Î ½¬ÇÁÆ® ÇÏ´Â º¸Á¶ÇÔ¼öÀÔ´Ï´Ù. const blocktype Get_LShiftedBlock(index x, length n) const; public: const BigInteger operator << (int leftmove) const; const BigInteger & operator <<=(int leftmove); const BigInteger operator >> (int rightmove) const; const BigInteger & operator >>=(int rightmove); #pragma endregion #pragma region »çÄ¢/³ª¸ÓÁö/Áõ°¨ private: void add(const BigInteger &Left, const BigInteger &Right); void subtract (const BigInteger &Left, const BigInteger &Right); void multiply(const BigInteger &Left, const BigInteger &Right); void divideWithRemainder(const BigInteger &Divisor, BigInteger &Quotient); public: // +, -, *, /, % // +=, -=, *=, /=, %= // -(´ÜÇ׿¬»êÀÚ), absÇÔ¼ö // ++, -- // µîÀ» Á¦°øÇÕ´Ï´Ù. const BigInteger operator - () const; friend const BigInteger abs(const BigInteger &x); const BigInteger add(const BigInteger &x) const; const BigInteger operator + (const BigInteger &x) const; const BigInteger & operator +=(const BigInteger &x); const BigInteger subtract(const BigInteger &x) const; const BigInteger operator - (const BigInteger &x) const; const BigInteger & operator -=(const BigInteger &x); const BigInteger multiply(const BigInteger &x) const; const BigInteger operator * (const BigInteger &x) const; const BigInteger & operator *=(const BigInteger &x); const BigInteger divide(const BigInteger &x) const; const BigInteger mod(const BigInteger &x) const; const BigInteger operator / (const BigInteger &x) const; const BigInteger operator % (const BigInteger &x) const; const BigInteger & operator /=(const BigInteger &x); const BigInteger & operator %=(const BigInteger &x); template const BigInteger operator +(const X &x) const; template const BigInteger operator -(const X &x) const; template const BigInteger operator *(const X &x) const; template const BigInteger operator /(const X &x) const; template const BigInteger operator %(const X &x) const; template friend const BigInteger operator +(const X &x, const BigInteger &y); template friend const BigInteger operator -(const X &x, const BigInteger &y); template friend const BigInteger operator *(const X &x, const BigInteger &y); template friend const BigInteger operator /(const X &x, const BigInteger &y); template friend const BigInteger operator %(const X &x, const BigInteger &y); template const BigInteger & operator +=(const X &x); template const BigInteger & operator -=(const X &x); template const BigInteger & operator *=(const X &x); template const BigInteger & operator /=(const X &x); template const BigInteger & operator %=(const X &x); template friend const X & operator +=(X &x, const BigInteger &y); template friend const X & operator -=(X &x, const BigInteger &y); template friend const X & operator *=(X &x, const BigInteger &y); template friend const X & operator /=(X &x, const BigInteger &y); template friend const X & operator %=(X &x, const BigInteger &y); private: void PlusOne(); void MinusOne(); public: BigInteger & operator ++(); const BigInteger operator ++(int dummy); BigInteger & operator --(); const BigInteger operator --(int dummy); #pragma endregion #pragma region ±âŸ¿¬»ê // °ÅµìÁ¦°ö friend BigInteger pow(const BigInteger &x, const BigInteger &y); template BigInteger pow(const BigInteger &x, const X &y); template BigInteger pow(const X &x, const BigInteger &y); // ÆÑÅ丮¾ó friend BigInteger factorial(const BigInteger &x); // ÃÖ´ë°ø¾à¼ö friend BigInteger gcd(BigInteger x, BigInteger y); template BigInteger gcd(BigInteger x, X y); template BigInteger gcd(X x, BigInteger y); // ÃÖ¼Ò°ø¹è¼ö friend BigInteger lcm(BigInteger x,BigInteger y); template BigInteger lcm(BigInteger x, X y); template BigInteger lcm(X x, BigInteger y); #pragma endregion }; #pragma region ÅÛÇø´Á¤ÀÇ #pragma region »ý¼º/º¯È¯-Á¤ÀÇ template void BigInteger::ConversionAssist1(PRI x) { if (x != 0) { Allocate(1); blk[0] = blocktype(x); sign = Positive; } else { SetZero(); } } template <> void BigInteger::ConversionAssist1(unsigned long long x) { // 0 ó¸® if (x == 0) { SetZero(); return; } if ( (x >> 32) == 0 ) // »óÀ§ 32ºñÆ®°¡ ºñ¾îÀÖ´Ù¸é { Allocate(1); } else // »óÀ§ 32ºñÆ®¿¡ ¼ýÀÚ°¡ ÀÖ´Ù¸é { Allocate(2); blk[1] = blocktype(x >> 32); // xÀÇ »óÀ§ 32ºñÆ® ´ëÀÔ } blk[0] = blocktype(x); // xÀÇ ÇÏÀ§ 32ºñÆ® ´ëÀÔ sign = Positive; } template void BigInteger::ConversionAssist2(PRI x) { if (x != 0) { Allocate(1); if (x > 0) { blk[0] = blocktype(x); sign = Positive; } else if (x < 0) { blk[0] = blocktype(-x); sign = Negative; } } else { SetZero(); } } template <> void BigInteger::ConversionAssist2(long long x) { // 0 ó¸® if (x == 0) { SetZero(); return; } bool isminus = false; if (x < 0) { isminus = true; x = -x; } if ( (x >> 32) == 0 ) // »óÀ§ 32ºñÆ®°¡ ºñ¾îÀÖ´Ù¸é { Allocate(1); } else // »óÀ§ 32ºñÆ®¿¡ ¼ýÀÚ°¡ ÀÖ´Ù¸é { Allocate(2); blk[1] = blocktype(x >> 32); // xÀÇ »óÀ§ 32ºñÆ® ´ëÀÔ } blk[0] = blocktype(x); // xÀÇ ÇÏÀ§ 32ºñÆ® ´ëÀÔ sign = (isminus == true) ? Negative : Positive; } template const PRI BigInteger::ConversionAssist3() const { if (sign == Negative) { #if defined(_DEBUG) throw "À½¼ö¸¦ Unsigned·Î ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù."; #else return PRI(0); #endif } if (len == 0) return PRI(0); #ifdef _DEBUG if (len == 1) #endif { PRI x = PRI(blk[0]); if (blocktype(x) == blk[0]) return x; } #ifdef _DEBUG throw "°ªÀÌ ³Ê¹« Ä¿¼­ º¯È¯ ÇÒ ¼ö ¾ø½À´Ï´Ù."; #else return PRI(0); #endif } template <> const unsigned long long BigInteger::ConversionAssist3() const { unsigned long long x = 0; if (sign == Zero) return x; else if (sign == Negative) { #if defined(_DEBUG) throw "À½¼ö¸¦ Unsigned·Î ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù."; #else return x; #endif } else if (len <= 2) { x = blk[0]; if (len == 1) return x; x += unsigned long long(blk[1]) << 32; return x; } #if defined(_DEBUG) throw "°ªÀÌ ³Ê¹« Ä¿¼­ º¯È¯ ÇÒ ¼ö ¾ø½À´Ï´Ù."; #else return x; #endif } template const PRI BigInteger::ConversionAssist4() const { /* * blk[0]ÀÇ ÃÖ°í ºñÆ®°¡ 1ÀÎ °æ¿ì, * º¯È¯°ª¿¡¼­ ¼ýÀÚ¸¦ À½¼ö·Î ÀνÄÇÏ´Â ¿À·ù°¡ »ý±ä´Ù. * µû¶ó¼­, ¾ÖÃÊ¿¡ ÀÌ·± º¯È¯Àº ±ÝÁöÇÑ´Ù. */ if (len == 0) return PRI(0); #ifdef _DEBUG if (len == 1 && !(blk[0] >> 31) ) { #endif PRI x = PRI(blk[0]); if (blocktype(x) == blk[0]) return (sign == Positive) ? x : -x; #ifdef _DEBUG } #endif #ifdef _DEBUG throw "°ªÀÌ ³Ê¹« Ä¿¼­ º¯È¯ ÇÒ ¼ö ¾ø½À´Ï´Ù."; #else return PRI(0); #endif } template <> const long long BigInteger::ConversionAssist4() const { long long x = 0; if (sign == Zero) return x; else if (len <= 2) { x = blk[0]; if (len == 2 && !(blk[1] >> 31) ) x += long long(blk[1]) << 32; } #if defined(_DEBUG) else { throw "°ªÀÌ ³Ê¹« Ä¿¼­ º¯È¯ ÇÒ ¼ö ¾ø½À´Ï´Ù."; } #endif return (sign == Positive) ? x : -x; } #pragma endregion #pragma region ºñ±³¿¬»ê-Á¤ÀÇ template bool BigInteger::operator ==(const X &x) const {return *this == (BigInteger(x));} template bool BigInteger::operator !=(const X &x) const {return *this != (BigInteger(x));} template bool BigInteger::operator > (const X &x) const {return *this > (BigInteger(x));} template bool BigInteger::operator >=(const X &x) const {return *this >= (BigInteger(x));} template bool BigInteger::operator < (const X &x) const {return *this < (BigInteger(x));} template bool BigInteger::operator <=(const X &x) const {return *this <= (BigInteger(x));} template bool operator ==(const X &x, const BigInteger &y) { return BigInteger(x) == y; } template bool operator !=(const X &x, const BigInteger &y) { return BigInteger(x) != y; } template bool operator > (const X &x, const BigInteger &y) { return BigInteger(x) > y; } template bool operator >=(const X &x, const BigInteger &y) { return BigInteger(x) >= y; } template bool operator < (const X &x, const BigInteger &y) { return BigInteger(x) < y; } template bool operator <=(const X &x, const BigInteger &y) { return BigInteger(x) <= y; } #pragma endregion #pragma region ºñÆ®¿¬»ê-Á¤ÀÇ template const BigInteger BigInteger::operator & (const X &x) const {return *this & BigInteger(x); } template const BigInteger BigInteger::operator | (const X &x) const {return *this | BigInteger(x); } template const BigInteger BigInteger::operator ^ (const X &x) const {return *this ^ BigInteger(x); } template const BigInteger BigInteger::operator &=(const X &x) {return *this = *this & BigInteger(x); } template const BigInteger BigInteger::operator |=(const X &x) {return *this = *this | BigInteger(x); } template const BigInteger BigInteger::operator ^=(const X &x) {return *this = *this ^ BigInteger(x); } template const BigInteger operator & (const X &x, const BigInteger &y) { return BigInteger(x) & y; } template const BigInteger operator | (const X &x, const BigInteger &y) { return BigInteger(x) | y; } template const BigInteger operator ^ (const X &x, const BigInteger &y) { return BigInteger(x) ^ y; } template const X & operator &=(X &x, const BigInteger &y) {return x = x & y;} template const X & operator |=(X &x, const BigInteger &y) {return x = x | y;} template const X & operator ^=(X &x, const BigInteger &y) {return x = x ^ y;} #pragma endregion #pragma region »çÄ¢/³ª¸ÓÁö/Áõ°¨¿¬»ê-Á¤ÀÇ template const BigInteger BigInteger::operator +(const X &x) const { return *this + BigInteger(x); } template const BigInteger BigInteger::operator -(const X &x) const { return *this - BigInteger(x); } template const BigInteger BigInteger::operator *(const X &x) const { return *this * BigInteger(x); } template const BigInteger BigInteger::operator /(const X &x) const { return *this / BigInteger(x); } template const BigInteger BigInteger::operator %(const X &x) const { return *this % BigInteger(x); } // y == BigInteger(x)·Î ÇÏ¸é ¹«ÇÑ Àç±ÍÈ£Ã⠹߻ý!!! template const BigInteger operator +(const X &x, const BigInteger &y) { return BigInteger(x) + y; } template const BigInteger operator -(const X &x, const BigInteger &y) { return BigInteger(x) - y; } template const BigInteger operator *(const X &x, const BigInteger &y) { return BigInteger(x) * y; } template const BigInteger operator /(const X &x, const BigInteger &y) { return BigInteger(x) / y; } template const BigInteger operator %(const X &x, const BigInteger &y) { return BigInteger(x) % y; } template const BigInteger & BigInteger::operator +=(const X &x) { return *this = *this + BigInteger(x); } template const BigInteger & BigInteger::operator -=(const X &x) { return *this = *this - BigInteger(x); } template const BigInteger & BigInteger::operator *=(const X &x) { return *this = *this * BigInteger(x); } template const BigInteger & BigInteger::operator /=(const X &x) { return *this = *this / BigInteger(x); } template const BigInteger & BigInteger::operator %=(const X &x) { return *this = *this % BigInteger(x); } template const X & operator +=(X &x, const BigInteger &y) {return x = x + y;} template const X & operator -=(X &x, const BigInteger &y) {return x = x - y;} template const X & operator *=(X &x, const BigInteger &y) {return x = x * y;} template const X & operator /=(X &x, const BigInteger &y) {return x = x / y;} template const X & operator %=(X &x, const BigInteger &y) {return x = x % y;} #pragma endregion #pragma region //±âŸ¿¬»ê-Á¤ÀÇ template BigInteger pow(const BigInteger &x, const X &y){return pow(x, BigInteger(y));} template BigInteger pow(const X &x, const BigInteger &y){return pow(BigInteger(x), y);} template BigInteger gcd(BigInteger x, X y) {return gcd(x, BigInteger(y));} template BigInteger gcd(X x, BigInteger y) {return gcd(BigInteger(x), y);} template BigInteger lcm(BigInteger x, X y) {return lcm(x, BigInteger(y));} template BigInteger lcm(X x, BigInteger y) {return lcm(BigInteger(x), y);} #pragma endregion #pragma endregion #endif /* _BIGINTEGER_H_ */