【发布时间】:2016-02-24 10:13:22
【问题描述】:
我正在努力更好地了解“大数字”库的工作原理(例如 GMP)。
我想写自己的函数到Add()/Subtract()/Multiply()/Divide()
类是传统定义的......
std::vector<unsigned char> _numbers; // all the numbers
bool _neg; // positive or negative number
long _decimalPos; // where the decimal point is located
// so 10.5 would be 1
// 10.25 would be 2
// 10 would be 0 for example
首先我需要将数字标准化,这样我才能做到
使用 2 个数字 10(x) + 10.25(y) = 20.25
为简单起见,我会让它们的长度相同,
对于 x: _numbers = (1,0,0,0) 十进制 = 2
对于 y: _numbers = (1,0,2,5) 十进制 = 2
然后我可以在循环中反向添加 x 到 y
...
// where x is 10.00 and y is 10.25
...
unsigned char carryOver = 0;
int totalLen = x._numbers.size();
for (size_t i = totalLen; i > 1 ; --i )
{
unsigned char sum = x._numbers[i-1] + y._numbers[i-1] + carryOver;
carryOver = 0;
if (sum > _base)
{
sum -= _base;
carryOver = 1;
}
numbers.insert( number.begin(), sum);
}
// any left over?
if (carryOver > 0)
{
numbers.insert( number.begin(), 1 );
}
// decimal pos is the same for this number as x and y
...
上面的示例适用于将两个正数相加,但一旦我需要将一个负数与一个正数相加,就会很快失败。
当涉及到减法时,这会变得更加复杂,而对于乘法和除法则更糟。
有人可以建议一些简单的函数来加()/减()/乘()/除()
我不是想重写/改进库,我只是想了解它们如何处理数字。
【问题讨论】:
-
如果你知道如何用铅笔和纸做长算术,你就不需要图书馆。如果您不这样做,图书馆将无法帮助您。
-
至少你处理的是简单而不是复杂的数字.. :P
-
您是否尝试过实现这种功能? (在gmplib.org/devel/repo-usage.html 上),您可能会比我们在这里用 2 或 3 行给出的实现细节有更好的了解。尽管如此,我会说人们编写 lib 正是因为他们不想在使用 lib 时为实现的复杂性而烦恼。如果事情是微不足道的而且非常简单,可能你甚至不会考虑将它们变成一个库。
-
是的,我确实看过它,但出于显而易见的原因,他们优化了很多代码,并且在其中一些优化中丢失了简单计算的完成方式。我只是想尝试了解其中一些库的逻辑。
-
@FFMG 编辑完成
标签: c++ math computation-theory bignum