最近看到身边有中学生用C++写大整数加减乘除,我也试着写了一下。
思路是用一堆无符号32位整数连接在一起,需要借助原生的64位整数加法和乘法运算。
本人不是计算机专业,这是我第0次在CSDN上贴代码,欢迎挑虫,轻喷。
MYUINT4000.H
#pragma once
#include <iostream>
#define MYUINT32_MAX_UI64 (0xffffffffui64)
#define MYHIBIWORD(MYUInt64) (static_cast<MYUINT32>(MYUInt64 >> 32))
#define MYLOBIWORD(MYUInt64) (static_cast<MYUINT32>(MYUInt64 & MYUINT32_MAX_UI64))
class MYUINT4000 /* 无符号四千位(二进制)整数类 */
{
typedef unsigned long long MYUINT64;
typedef unsigned int MYUINT32;
typedef signed int MYINT32;
typedef signed long long MYINT64;
protected:
MYUINT32 _m_[125]; /* 下标0是最低位 */
protected:
MYUINT4000(MYINT32 dgt, MYUINT64 m) : MYUINT4000() { this->_m_[dgt] = MYLOBIWORD(m); if (dgt < 124) { this->_m_[dgt + 1] = MYHIBIWORD(m); } }
MYINT32 m_dgt() const { MYINT32 cnt; for (cnt = 124; cnt >= 0; cnt--) { if (this->_m_[cnt] != 0) { break; } } return (cnt + 1); }
void state(MYINT32 dgt) { this->_m_[dgt / 32] += (MYUINT32)(1) << (dgt % 32); }
bool operator[](MYINT32 dgt) const { if (this->_m_[dgt / 32] & ((MYUINT32)(1) << (dgt % 32))) { return (true); } else { return (false); } }
static void addone(char* dec) { dec[0] += 1; for (MYINT32 dgt = 0; dec[dgt] > '9'; dgt++) { dec[dgt] = '0'; dec[dgt + 1] += 1; } }
static void bytwo(char* dec)
{
MYINT32 dgt;
char temp;
char carry = 0;
for (dgt = 0; dec[dgt] != '\0'; dgt++)
{
temp = (dec[dgt] - '0') * 2 + carry;
if (temp > 9) { carry = 1; dec[dgt] = temp - 10 + '0'; }
else { carry = 0; dec[dgt] = temp + '0'; }
}
if (carry == 1) { dec[dgt] = '1'; }
}
public:
MYUINT4000() { for (MYINT32 cnt = 0; cnt < 125; cnt++) { this->_m_[cnt] = 0; } }
MYUINT4000(MYUINT32 low) : MYUINT4000() { this->_m_[0] = low; }
MYUINT4000(MYUINT64 low) : MYUINT4000() { this->_m_[0] = MYLOBIWORD(low); this->_m_[1] = MYHIBIWORD(low); }
MYUINT4000(MYINT32 low) { if (low >= 0) { (*this) = MYUINT4000(static_cast<MYUINT32>(low)); } else { (*this) = -MYUINT4000(static_cast<MYUINT32>(-low)); } }
MYUINT4000(MYINT64 low) { if (low >= 0) { (*this) = MYUINT4000(static_cast<MYUINT64>(low)); } else { (*this) = -MYUINT4000(static_cast<MYUINT64>(-low)); } }
MYUINT4000 operator+(const MYUINT4000 another) const
{
MYUINT64 temp;
MYUINT64 carry = 0;
MYUINT4000 res;
for (MYINT32 cnt = 0; cnt < 125; cnt++)
{
temp = static_cast<MYUINT64>(this->_m_[cnt]) + static_cast<MYUINT64>(another._m_[cnt]) + carry;
if (temp > MYUINT32_MAX_UI64) { carry = 1; }
else { carry = 0; }
res._m_[cnt] = MYLOBIWORD(temp);
}
return (res);
}
MYUINT4000 operator~() const
{
MYUINT4000 res;
for (MYINT32 cnt = 0; cnt < 125; cnt++)
{
res._m_[cnt] = ~(this->_m_[cnt]);
}
return (res);
}
MYUINT4000 operator-() const { return ((~(*this)) + MYUINT4000(1)); }
MYUINT4000 operator-(const MYUINT4000 another) const { return ((*this) + (-(another))); }
MYUINT4000 operator*(const MYUINT4000 another) const
{
MYUINT64 temp;
MYUINT32 carry = 0;
MYUINT4000 res(0);
for (MYINT32 dgt = 0; dgt < 125; dgt++)
{
temp = 0;
for (MYINT32 cnt = 0; cnt <= dgt; cnt++)
{
temp = temp + static_cast<MYUINT64>(this->_m_[cnt]) * static_cast<MYUINT64>(another._m_[dgt - cnt]);
}
res = res + MYUINT4000(dgt, temp);
}
return (res);
}
bool operator==(const MYUINT4000 another) const
{
for (MYINT32 cnt = 124; cnt >= 0; cnt--)
{
if (this->_m_[cnt] != another._m_[cnt]) { return (false); }
}
return (true);
}
bool operator<(const MYUINT4000 another) const
{
for (MYINT32 cnt = 124; cnt >= 0; cnt--)
{
if (this->_m_[cnt] < another._m_[cnt]) { return (true); }
else if (this->_m_[cnt] > another._m_[cnt]) { return (false); }
}
return (false);
}
bool operator>(const MYUINT4000 another) const
{
for (MYINT32 cnt = 124; cnt >= 0; cnt--)
{
if (this->_m_[cnt] > another._m_[cnt]) { return (true); }
else if (this->_m_[cnt] < another._m_[cnt]) { return (false); }
}
return (false);
}
bool operator>=(const MYUINT4000 another) const { return (!((*this) < another)); }
bool operator<=(const MYUINT4000 another) const { return (!((*this) > another)); }
MYUINT4000 operator>>(MYINT32 dgt) const
{
MYUINT4000 res(0);
MYUINT4000 res1(0);
MYUINT64 temp;
MYINT32 dgt_m = dgt / 32;
dgt = dgt % 32;
for (MYINT32 cnt = 0; cnt < 125 - dgt_m; cnt++)
{
res._m_[cnt] = this->_m_[cnt + dgt_m];
}
for (MYINT32 cnt = 124; cnt >= 1; cnt--)
{
temp = (static_cast<MYUINT64>(res._m_[cnt])) << (32 - dgt);
res1._m_[cnt] = res1._m_[cnt] + MYHIBIWORD(temp);
res1._m_[cnt - 1] = res1._m_[cnt - 1] + MYLOBIWORD(temp);
}
temp = (static_cast<MYUINT64>(res._m_[0])) << (32 - dgt);
res1._m_[0] = res1._m_[0] + MYHIBIWORD(temp);
return (res1);
}
MYUINT4000 operator<<(MYINT32 dgt) const
{
MYUINT4000 res(0);
MYUINT4000 res1(0);
MYUINT64 temp;
MYINT32 dgt_m = dgt / 32;
dgt = dgt % 32;
for (MYINT32 cnt = dgt_m; cnt < 125; cnt++)
{
res._m_[cnt] = this->_m_[cnt - dgt_m];
}
for (MYINT32 cnt = 0; cnt < 124; cnt++)
{
temp = (static_cast<MYUINT64>(res._m_[cnt])) << dgt;
res1._m_[cnt + 1] = res1._m_[cnt + 1] + MYHIBIWORD(temp);
res1._m_[cnt] = res1._m_[cnt] + MYLOBIWORD(temp);
}
temp = (static_cast<MYUINT64>(res._m_[124])) << dgt;
res1._m_[124] = res1._m_[124] + MYLOBIWORD(temp);
return (res1);
}
MYUINT4000 operator/(const MYUINT4000 another) const
{
/* 这个移位很头疼 */
MYUINT4000 num(*this);
MYUINT4000 den;
MYUINT4000 res(0);
MYINT32 dgt = (this->m_dgt() - another.m_dgt() + 1) * 32;
den = another << dgt;
if (dgt < 0) { return (MYUINT4000(0)); }
for (MYINT32 cnt = dgt; cnt >= 0; cnt--)
{
if (num >= den)
{
num = num - den;
res.state(cnt);
}
den = den >> 1;
}
return (res);
}
MYUINT4000 operator&(const MYUINT4000 another) const { MYUINT4000 res; for (MYINT32 cnt = 0; cnt < 125; cnt++) { res._m_[cnt] = this->_m_[cnt] & another._m_[cnt]; } return (res); }
MYUINT4000 operator|(const MYUINT4000 another) const { MYUINT4000 res; for (MYINT32 cnt = 0; cnt < 125; cnt++) { res._m_[cnt] = this->_m_[cnt] | another._m_[cnt]; } return (res); }
friend std::ostream& operator<<(std::ostream& out, const MYUINT4000 myUInt4000)
{
char dec[1210] = { '0' };
for (MYINT32 cnt = 3999; cnt >= 1; cnt--)
{
if (myUInt4000[cnt]) { addone(dec); }
bytwo(dec);
}
if (myUInt4000[0]) { addone(dec); }
for (MYINT32 pos = strlen(dec) - 1; pos >= 0; pos--) { out << dec[pos]; }
return (out);
}
void print(const char* sep = "_", const char* end = "\n") const
{
for (MYINT32 cnt = 124; cnt >= 1; cnt--)
{
printf("%08X%s", this->_m_[cnt], sep);
}
printf("%08X%s", this->_m_[0], end);
}
};
|