#include <cmath>
#include <stack>
#include "maths.h"
/*
说明:本源码遵循BSD开源协议:使用、修改时,请不要修改命名空间
*/
namespace ljs
{
char Integer::dec2hex(Integer c) const
{
if (c == 0 || c._data.size() == 0)
{
return '0';
}
else if (c == 1)
{
return '1';
}
else if (c == 2)
{
return '2';
}
else if (c == 3)
{
return '3';
}
else if (c == 4)
{
return '4';
}
else if (c == 5)
{
return '5';
}
else if (c == 6)
{
return '6';
}
else if (c == 7)
{
return '7';
}
else if (c == 8)
{
return '8';
}
else if (c == 9)
{
return '9';
}
else if (c == 10)
{
return 'a';
}
else if (c == 11)
{
return 'b';
}
else if (c == 12)
{
return 'c';
}
else if (c == 13)
{
return 'd';
}
else if (c == 14)
{
return 'e';
}
else if (c == 15)
{
return 'f';
}
return '0';
}
Integer::Integer()
{
clear();
}
Integer::Integer(long long num)
{
clear();
do {
_data.push_back(num % _base);
num = num / _base;
} while (num > 0);
}
Integer::Integer(const std::string str)
{
clear();
if (str.length() == 0)
{
return;
}
if (str.at(0) == '-')
{
_sign = false;
}
int x;
long long len = (str.length() - 1) / 8 + 1;
for (int i = 0; i < len; i++)
{
long long end = str.length() - i * 8;
long long start = max(0, end - 8);
sscanf_s(str.substr(start, end - start).c_str(), "%d", &x);
_data.push_back(x);
}
}
Integer::~Integer()
{
clear();
}
void Integer::clear()
{
_data.clear();
_sign = true;
}
size_t Integer::length() const
{
size_t x = 0;
if (_data.size() > 0)
{
x += 8 * (_data.size() - 1);
int y = _data.at(_data.size() - 1);
for (; y > 0; ++x) y /= 10;
}
return x;
}
short Integer::bit(size_t i) const
{
return (int(_data.at(i / 8))) / (int(std::pow(10, i % 8))) % 10;
}
bool Integer::is_odd() const
{
return !is_even();
}
bool Integer::is_even() const
{
return bit(0) % 2 == 0;
}
Integer Integer::hex_str(const std::string str)
{
clear();
std::string hexs = "";
long long n = str.length();
int s = 0;
int d;
Integer tp;
while (--n > -1)
{
tp = "16";
tp = tp.power(n);
if (str.at(s) <= '9' && str.at(s) >= '0')
{
d = str.at(s) - '0';
}
else if (str.at(s) <= 'f' && str.at(s) >= 'a')
{
d = str.at(s) - 'a';
d += 10;
}
else if (str.at(s) <= 'F' && str.at(s) >= 'A')
{
d = str.at(s) - 'A';
d += 10;
}
s++;
tp = tp * d;
*this += tp;
}
return *this;
}
std::string Integer::hex_str() const
{
std::string hexs;
hexs = "";
Integer tp = *this;
while (tp > 0)
{
hexs = dec2hex(tp % 16) + hexs;
tp = tp / 16;
}
return hexs;
}
Integer Integer::dec_str(const std::string str)
{
*this = str;
return *this;
}
std::string Integer::dec_str() const
{
std::string res;
res = "";
for (int i = 0; i < _data.size(); i++)
{
if (i == _data.size() - 1)
{
std::string sstemp = std::to_string(_data.at(i));
res = sstemp + res;
}
else
{
int n = _data.at(i);
char temp[10];
memset(temp, 0, 10);
sprintf_s(temp, 10, "%08d", n);
res = temp + res;
}
}
if (res == "")
res = "0";
if (!_sign && res != "0")
res = "-" + res;
return res;
}
Integer Integer::operator=(long long num)
{
clear();
do {
_data.push_back(num % _base);
num = num / _base;
} while (num > 0);
return *this;
}
Integer Integer::operator=(const std::string str)
{
clear();
if (str.length() == 0)
{
return *this;
}
if (str.at(0) == '-')
{
_sign = false;
}
int x;
long long len = (str.length() - 1) / 8 + 1;
for (int i = 0; i < len; i++)
{
long long end = str.length() - i * 8;
long long start = max(0, end - 8);
sscanf_s(str.substr(start, end - start).c_str(), "%d", &x);
_data.push_back(x);
}
return *this;
}
bool Integer::operator<(const Integer& num) const
{
if (!_sign && num._sign)
{
return true;
}
if (_sign && !num._sign)
{
return false;
}
if (!_sign && !num._sign)
{
Integer a = *this;
a._sign = true;
Integer b = num;
b._sign = true;
return b < a;
}
if (_data.size() != num._data.size())
return _data.size() < num._data.size();
for (long long i = _data.size() - 1; i >= 0; i--)
if (_data.at(i) != num._data.at(i))
return _data.at(i) < num._data.at(i);
return false;
}
bool Integer::operator>(const Integer& num)const
{
return num < *this;
}
bool Integer::operator<=(const Integer& num)const
{
return !(*this > num);
}
bool Integer::operator>=(const Integer& num)const
{
return !(*this < num);
}
bool Integer::operator!=(const Integer& num)const
{
return *this > num || *this < num;
}
bool Integer::operator==(const Integer& num)const
{
return !(num != *this);
}
Integer Integer::operator+(const Integer& num) const
{
if (_sign ^ num._sign)
{
Integer tmp = _sign ? num : *this;
tmp._sign = true;
return _sign ? *this - tmp : num - tmp;
}
Integer c;
int g = 0;
for (int i = 0;; i++)
{
if (g == 0 && i >= _data.size() && i >= num._data.size()) break;
int x = g;
if (i < _data.size())
{
x += _data.at(i);
}
if (i < num._data.size())
{
x += num._data.at(i);
}
c._data.push_back(x % _base);
g = x / _base;
}
while (g > 0)
{
c._data.push_back(g % _base);
g = g / _base;
}
c._sign = _sign;
return c;
}
Integer Integer::operator++()
{
*this = *this + 1;
return *this;
}
Integer Integer::operator+=(const Integer& num)
{
*this = *this + num;
return *this;
}
Integer Integer::operator-(const Integer& num) const
{
Integer a = *this, b = num;
if (!num._sign && !_sign)
{
b._sign = true;
a._sign = true;
return b - a;
}
if (!b._sign)
{
b._sign = true;
return a + b;
}
if (!a._sign)
{
a._sign = true;
b = a + b;
b._sign = false;
return b;
}
Integer c;
if (a == b)
{
return c;
}
if (a < b)
{
c = (b - a);
c._sign = false;
return c;
}
int i;
int h = 0;
int x = 0;
for (i = 0; i < b._data.size(); i++)
{
int m = a._data.at(i) - h;
int n = b._data.at(i);
if (m < n)
{
h = 1;
m += _base;
x += (m - n);
}
else
{
h = 0;
x += (m - n);
}
c._data.push_back(x % _base);
x = x / _base;
}
x -= h;
for (; i < a._data.size(); i++) {
x += a._data[i];
c._data.push_back(x % _base);
x = x / _base;
}
while (x > 0)
{
c._data.push_back(x % _base);
x = x / _base;
}
while (c._data.at(c._data.size() - 1) == 0)
{
c._data.pop_back();
}
return c;
}
Integer Integer::operator--()
{
*this = *this - 1;
return *this;
}
Integer Integer::operator-=(const Integer& num)
{
*this = *this - num;
return *this;
}
Integer Integer::operator*(const Integer& num)const
{
Integer b;
for (int i = 0; i < _data.size(); i++)
{
Integer c;
long long g = 0;
long long x = 0;
for (int k = 0; k < i; k++)
{
c._data.push_back(0);
}
long long m = _data.at(i);
for (int j = 0; j < num._data.size(); j++)
{
long long n = num._data.at(j);
x = g + m * n;
c._data.push_back(x % _base);
g = x / _base;
}
while (g > 0)
{
c._data.push_back(g % _base);
g = g / _base;
}
b += c;
}
b._sign = !(_sign ^ num._sign);
return b;
}
Integer Integer::operator*=(const
纯C++简易数学库,实现大整数、浮点数、复数(待补充)
需积分: 0 111 浏览量
更新于2023-02-27
收藏 4KB ZIP 举报
在IT领域,编程语言C++以其高效性和灵活性深受程序员喜爱,尤其在处理底层系统和高性能计算方面。本项目提供了一个纯C++实现的简易数学库,专注于大整数、浮点数以及复数的运算。这个库利用了C++标准库中的`std::vector`来存储和操作大数,使得在内存管理上更加方便,同时也为理解和实现大数运算提供了简洁的代码结构。
大数运算通常在处理超出普通整型范围的数值时显得尤为重要,例如在加密算法、分布式计算或者科学计算中。C++标准库并未内置大数运算支持,因此开发者需要自定义数据结构和算法来实现这一功能。在这个库中,大整数是通过`std::vector<unsigned char>`来表示的,这是因为每个`unsigned char`可以存储0-255的值,通过多个字节的组合,可以表示任意大小的整数。
具体来说,大整数的加减乘除可以通过位运算和数组操作来实现。例如,加法可以采用类似于学校里学习的竖式加法方法,从低位到高位逐位相加,并考虑进位;减法则类似,但可能需要借位;乘法可以采用Karatsuba算法或更简单的Long Multiplication;除法则可能需要使用Long Division,或者更高效的算法如Newton-Raphson迭代法。这些操作都需要考虑到`std::vector`的大小调整和边界条件。
浮点数的运算则更为复杂,因为涉及到精度问题和浮点数的二进制表示。在没有硬件支持的情况下,可以使用Ieee754标准来模拟浮点数的运算。这通常包括将浮点数转换为二进制形式,进行位操作,然后将结果转换回十进制。复数的运算则涉及实部和虚部的加减乘除,以及复数的共轭、模长和幅角计算。
为了确保正确性,这个库应当包含详尽的单元测试,覆盖所有可能的操作和边界情况,比如零除、溢出等。此外,良好的文档也是必不可少的,它可以帮助其他开发者理解库的使用方法和内部机制。
这个C++简易数学库提供了一个基础的框架,允许开发者在C++环境中进行大数、浮点数和复数的计算。它不仅展示了如何利用`std::vector`来处理大数,还展示了如何在没有内置支持的情况下实现复杂的数学运算。对于学习C++和算法的开发者来说,这是一个很好的实践项目,也可以作为实际项目中扩展数学功能的基础。同时,对于需要处理大量数值计算的软件,这个库能作为一个高效的解决方案。
mycsdn8019
- 粉丝: 1
- 资源: 12
最新资源
- 【全年行事历】5团建医药箱常备药清单.docx
- 【全年行事历】4团建活动物料清单.xlsx
- 【全年行事历】7团建活动策划书.docx
- 【全年行事历】ZOL团建活动策划方案.pptx
- 【全年行事历】XXX团建活动计划.pptx
- 【全年行事历】86团建活动培训PPT完.pptx
- 【全年行事历】公司年度活动计划.xls
- 【全年行事历】大型企业公司活动进度表.xlsx
- 【全年行事历】公司户外团建活动方案-某公司.pptx
- 【全年行事历】公司团建费用统计表.xlsx
- 【全年行事历】公司团建拓展行程方案-模版.docx
- 【全年行事历】公司全年团建活动方案.xls
- 【全年行事历】公司员工一年度关怀方案预算.xls
- 【全年行事历】公司团建活动项目介绍.pptx
- 【全年行事历】行政部年度活动策划及经费预算.xlsx
- 【全年行事历】行政全年活动筹备规划.xlsx