如何在c++中实现大整数

时间:2022-04-22 16:51:19

I'd like to implement a big int class in C++ as a programming exercise—a class that can handle numbers bigger than a long int. I know that there are several open source implementations out there already, but I'd like to write my own. I'm trying to get a feel for what the right approach is.

我想在c++中实现一个大的int类作为编程练习——一个可以处理大于长int数的类。我想知道正确的方法是什么。

I understand that the general strategy is get the number as a string, and then break it up into smaller numbers (single digits for example), and place them in an array. At this point it should be relatively simple to implement the various comparison operators. My main concern is how I would implement things like addition and multiplication.

我知道一般的策略是将数字作为字符串获取,然后将其分解为更小的数字(例如,个位数),并将它们放在一个数组中。此时,实现各种比较运算符应该相对简单。我主要关心的是如何实现加法和乘法。

I'm looking for a general approach and advice as opposed to actual working code.

我正在寻找一个通用的方法和建议,而不是实际的工作代码。

15 个解决方案

#1


35  

Things to consider for a big int class:

对于一个大的int类需要考虑的事项:

  1. Mathematical operators: +, -, /, *, % Don't forget that your class may be on either side of the operator, that the operators can be chained, that one of the operands could be an int, float, double, etc.

    数学运算符:+,-,/,*,%不要忘记你的类可能在运算符的两边,运算符可以被链化,一个操作数可以是int, float, double,等等。

  2. I/O operators: >>, << This is where you figure out how to properly create your class from user input, and how to format it for output as well.

    I/O操作符:>>,< This is where you figure how to create your class from user input, and how to format for output。

  3. Conversions/Casts: Figure out what types/classes your big int class should be convertible to, and how to properly handle the conversion. A quick list would include double and float, and may include int (with proper bounds checking) and complex (assuming it can handle the range).

    转换/强制转换:确定您的大型int类应该转换为什么类型/类,以及如何正确地处理转换。一个快速列表将包含double和float,并且可能包含int(带有适当的边界检查)和complex(假设它可以处理范围)。

#2


40  

A fun challenge. :)

一个有趣的挑战。:)

I assume that you want integers of arbitrary length. I suggest the following approach:

我假设你想要任意长度的整数。我建议以下方法:

Consider the binary nature of the datatype "int". Think about using simple binary operations to emulate what the circuits in your CPU do when they add things. In case you are interested more in-depth, consider reading this wikipedia article on half-adders and full-adders. You'll be doing something similar to that, but you can go down as low level as that - but being lazy, I thought I'd just forego and find a even simpler solution.

考虑数据类型“int”的二进制性质。考虑使用简单的二进制操作来模拟CPU中的电路在添加东西时所做的事情。如果你有更深入的兴趣,可以考虑阅读这篇关于半加法器和全加法器的*文章。你将会做一些类似的事情,但是你可以降低到那样低的水平——但是由于懒惰,我认为我应该放弃去寻找一个更简单的解决方案。

But before going into any algorithmic details about adding, subtracting, multiplying, let's find some data structure. A simple way, is of course, to store things in a std::vector.

但是在讨论任何关于加、减、乘的算法细节之前,让我们先找到一些数据结构。当然,一种简单的方法是将东西存储在std::vector中。

template< class BaseType >
class BigInt
{
typedef typename BaseType BT;
protected: std::vector< BaseType > value_;
};

You might want to consider if you want to make the vector of a fixed size and if to preallocate it. Reason being that for diverse operations, you will have to go through each element of the vector - O(n). You might want to know offhand how complex an operation is going to be and a fixed n does just that.

您可能需要考虑是否要使向量具有固定的大小,以及是否预先分配它。因为对于不同的运算,你需要遍历向量的每个元素O(n)你可能想知道一个操作会有多复杂,一个固定的n会这样。

But now to some algorithms on operating on the numbers. You could do it on a logic-level, but we'll use that magic CPU power to calculate results. But what we'll take over from the logic-illustration of Half- and FullAdders is the way it deals with carries. As an example, consider how you'd implement the += operator. For each number in BigInt<>::value_, you'd add those and see if the result produces some form of carry. We won't be doing it bit-wise, but rely on the nature of our BaseType (be it long or int or short or whatever): it overflows.

但是现在来看看一些关于数字运算的算法。您可以在逻辑级别上完成,但是我们将使用这种神奇的CPU能力来计算结果。但是,我们将从“半边倒”和“富勒德”的逻辑阐释中接手,这是它处理“携带”的方式。例如,考虑如何实现+=运算符。对于BigInt<>: value_中的每个数字,您应该添加它们,看看结果是否产生某种形式的进位。我们不会把它做得很好,但要依赖于我们的基类型的性质(不管是长或短或短或其他):它会溢出。

Surely, if you add two numbers, the result must be greater than the greater one of those numbers, right? If it's not, then the result overflowed.

当然,如果你把两个数相加,结果一定大于其中一个数,对吧?如果不是,结果就会溢出。

template< class BaseType >
BigInt< BaseType >& BigInt< BaseType >::operator += (BigInt< BaseType > const& operand)
{
  BT count, carry = 0;
  for (count = 0; count < std::max(value_.size(), operand.value_.size(); count++)
  {
    BT op0 = count < value_.size() ? value_.at(count) : 0, 
       op1 = count < operand.value_.size() ? operand.value_.at(count) : 0;
    BT digits_result = op0 + op1 + carry;
    if (digits_result-carry < std::max(op0, op1)
    {
      BT carry_old = carry;
      carry = digits_result;
      digits_result = (op0 + op1 + carry) >> sizeof(BT)*8; // NOTE [1]
    }
    else carry = 0;
  }

  return *this;
}
// NOTE 1: I did not test this code. And I am not sure if this will work; if it does
//         not, then you must restrict BaseType to be the second biggest type 
//         available, i.e. a 32-bit int when you have a 64-bit long. Then use
//         a temporary or a cast to the mightier type and retrieve the upper bits. 
//         Or you do it bitwise. ;-)

The other arithmetic operation go analogous. Heck, you could even use the stl-functors std::plus and std::minus, std::times and std::divides, ..., but mind the carry. :) You can also implement multiplication and division by using your plus and minus operators, but that's very slow, because that would recalculate results you already calculated in prior calls to plus and minus in each iteration. There are a lot of good algorithms out there for this simple task, use wikipedia or the web.

另一种算术运算是类似的。见鬼,你甚至可以使用stl函数std::plus和std:: -, std::times和std: divide,…,但小心搬运。你也可以使用正负运算符来实现乘法和除法,但这是非常慢的,因为这将重新计算你在每次迭代中已经计算过的加减运算结果。对于这个简单的任务,有很多很好的算法,使用*或者网络。

And of course, you should implement standard operators such as operator<< (just shift each value in value_ to the left for n bits, starting at the value_.size()-1... oh and remember the carry :), operator< - you can even optimize a little here, checking the rough number of digits with size() first. And so on. Then make your class useful, by befriendig std::ostream operator<<.

当然,您应该实现诸如运算符<<(只是将value_中的每个值转换为n位的值,从value_.size()-1开始)。哦,记住进位:),运算符< -你甚至可以在这里优化一下,首先检查大小为()的数字的粗略数目。等等。然后使用befriendig std::ostream operator<。

Hope this approach is helpful!

希望这个方法能有所帮助!

#3


25  

There's a complete section on this: [The Art of Computer Programming, vol.2: Seminumerical Algorithms, section 4.3 Multiple Precision Arithmetic, pp. 265-318 (ed.3)]. You may find other interesting material in Chapter 4, Arithmetic.

关于这一点有一个完整的部分:[计算机程序设计的艺术,vol.2: Seminumerical算法,第4.3节多重精度算法,第265-318页(.3)]。你可以在第四章算术中找到其他有趣的材料。

If you really don't want to look at another implementation, have you considered what it is you are out to learn? There are innumerable mistakes to be made and uncovering those is instructive and also dangerous. There are also challenges in identifying important computational economies and having appropriate storage structures for avoiding serious performance problems.

如果您真的不想查看另一个实现,您是否考虑过要学习什么?我们要犯无数的错误,发现这些错误是有益的,也是危险的。在识别重要的计算经济和拥有适当的存储结构以避免严重的性能问题方面也存在挑战。

A Challenge Question for you: How do you intend to test your implementation and how do you propose to demonstrate that it's arithmetic is correct?

您面临的一个挑战是:您打算如何测试您的实现,以及您打算如何证明它的算术是正确的?

You might want another implementation to test against (without looking at how it does it), but it will take more than that to be able to generalize without expecting an excrutiating level of testing. Don't forget to consider failure modes (out of memory problems, out of stack, running too long, etc.).

您可能希望对另一个实现进行测试(而不考虑它是如何进行测试的),但是要想在不需要极度苛刻的测试级别的情况下进行归纳,还需要做更多的工作。不要忘记考虑失败模式(内存问题、堆栈之外、运行时间太长等等)。

Have fun!

玩得开心!

#4


6  

addition would probably have to be done in the standard linear time algorithm
but for multiplication you could try http://en.wikipedia.org/wiki/Karatsuba_algorithm

在标准线性时间算法中,可能需要做加法,但是对于乘法,可以尝试http://en.wikipedia.org/wiki/Karatsuba_algorithm

#5


5  

Once you have the digits of the number in an array, you can do addition and multiplication exactly as you would do them longhand.

一旦你在数组中有了数字,你就可以做加法和乘法,就像你长时间做一样。

#6


4  

Don't forget that you don't need to restrict yourself to 0-9 as digits, i.e. use bytes as digits (0-255) and you can still do long hand arithmetic the same as you would for decimal digits. You could even use an array of long.

不要忘记,您不需要将自己限制为0-9作为数字,也就是说,使用字节作为数字(0-255),并且您仍然可以像处理十进制数字那样做长手算术。你甚至可以使用一个长数组。

#7


3  

I'm not convinced using a string is the right way to go -- though I've never written code myself, I think that using an array of a base numeric type might be a better solution. The idea is that you'd simply extend what you've already got the same way the CPU extends a single bit into an integer.

我不相信使用字符串是正确的方法——尽管我自己从来没有编写过代码,但我认为使用基本数字类型的数组可能是更好的解决方案。其思想是,您只需将已经获得的内容扩展到CPU将单个位扩展为整数的方法。

For example, if you have a structure

例如,如果你有一个结构。

typedef struct {
    int high, low;
} BiggerInt;

You can then manually perform native operations on each of the "digits" (high and low, in this case), being mindful of overflow conditions:

然后,您可以手工对每个“数字”(在本例中为高或低)执行本机操作,注意溢出条件:

BiggerInt add( const BiggerInt *lhs, const BiggerInt *rhs ) {
    BiggerInt ret;

    /* Ideally, you'd want a better way to check for overflow conditions */
    if ( rhs->high < INT_MAX - lhs->high ) {
        /* With a variable-length (a real) BigInt, you'd allocate some more room here */
    }

    ret.high = lhs->high + rhs->high;

    if ( rhs->low < INT_MAX - lhs->low ) {
        /* No overflow */
        ret.low = lhs->low + rhs->low;
    }
    else {
        /* Overflow */
        ret.high += 1;
        ret.low = lhs->low - ( INT_MAX - rhs->low ); /* Right? */
    }

    return ret;
}

It's a bit of a simplistic example, but it should be fairly obvious how to extend to a structure that had a variable number of whatever base numeric class you're using.

这是一个有点简单的例子,但是很明显,如何扩展到具有任意基数值类的可变数量的结构。

#8


2  

Like others said, do it to old fashioned long-hand way, but stay away from doing this all in base 10. I'd suggest doing it all in base 65536, and storing things in an array of longs.

就像其他人说的,用老办法做,但是不要在10垒上做这些。我建议在65536的基础上做所有的事情,并把东西存储在一个长数组中。

#9


2  

Take a look here to see how GMP implements its algorithms.

看看GMP是如何实现它的算法的。

#10


1  

If your target architecture supports BCD (binary coded decimal) representation of numbers, you can get some hardware support for the longhand multiplication/addition that you need to do. Getting the compiler to emit BCD instruction is something you'll have to read up on...

如果您的目标体系结构支持BCD(二进制编码的十进制)数字表示,那么您可以获得一些硬件支持,以支持您需要进行的longhand乘法/加法。让编译器发出BCD指令是你必须阅读的东西……

The Motorola 68K series chips had this. Not that I'm bitter or anything.

摩托罗拉68K系列芯片就有这个功能。并不是说我很痛苦。

#11


0  

Use the algorithms you learned in 1st through 4th grade.
Start with the ones column, then the tens, and so forth.

使用你在一年级到四年级学到的算法。从一列开始,然后是十位,以此类推。

#12


0  

My start would be to have an arbitrary sized array of integers, using 31 bits and the 32n'd as overflow.

我的开始是有一个任意大小的整数数组,使用31位和32n的作为溢出。

The starter op would be ADD, and then, MAKE-NEGATIVE, using 2's complement. After that, subtraction flows trivially, and once you have add/sub, everything else is doable.

开始的操作是添加,然后,用2的补码。在那之后,减法就变得简单了,一旦你有了add/sub,其他的都是可行的。

There are probably more sophisticated approaches. But this would be the naive approach from digital logic.

可能还有更复杂的方法。但这将是数字逻辑的幼稚方法。

#13


0  

Could try implementing something like this:

可以尝试实现以下内容:

http://www.docjar.org/html/api/java/math/BigInteger.java.html

http://www.docjar.org/html/api/java/math/BigInteger.java.html

You'd only need 4 bits for a single digit 0 - 9

一个0 - 9位只需要4位

So an Int Value would allow up to 8 digits each. I decided i'd stick with an array of chars so i use double the memory but for me it's only being used 1 time.

所以一个Int值最多允许有8位数字。我决定使用一组字符,所以我用了两倍的内存,但对我来说,它只用了1次。

Also when storing all the digits in a single int it over-complicates it and if anything it may even slow it down.

同时,当将所有的数字存储在一个整数中时,它会使它变得过于复杂,甚至可能会减慢它的速度。

I don't have any speed tests but looking at the java version of BigInteger it seems like it's doing an awful lot of work.

我没有任何速度测试,但是看看java版本的BigInteger,它似乎做了很多工作。

For me I do the below

对于我,我做下面的

//Number = 100,000.00, Number Digits = 32, Decimal Digits = 2.
BigDecimal *decimal = new BigDecimal("100000.00", 32, 2);
decimal += "1000.99";
cout << decimal->GetValue(0x1 | 0x2) << endl; //Format and show decimals.
//Prints: 101,000.99

#14


-1  

subtract 48 from your string of integer and print to get number of large digit. then perform the basic mathematical operation . otherwise i will provide complete solution.

从您的整数字符串中减去48,然后打印以获得大数字。然后进行基本的数学运算。否则我会提供完整的解决方案。

#15


-1  

C++ class BigInt that enables the user to work with arbitrary precision integers. http://sourceforge.net/projects/cpp-bigint/

c++类BigInt,允许用户处理任意精度的整数。http://sourceforge.net/projects/cpp-bigint/

#1


35  

Things to consider for a big int class:

对于一个大的int类需要考虑的事项:

  1. Mathematical operators: +, -, /, *, % Don't forget that your class may be on either side of the operator, that the operators can be chained, that one of the operands could be an int, float, double, etc.

    数学运算符:+,-,/,*,%不要忘记你的类可能在运算符的两边,运算符可以被链化,一个操作数可以是int, float, double,等等。

  2. I/O operators: >>, << This is where you figure out how to properly create your class from user input, and how to format it for output as well.

    I/O操作符:>>,< This is where you figure how to create your class from user input, and how to format for output。

  3. Conversions/Casts: Figure out what types/classes your big int class should be convertible to, and how to properly handle the conversion. A quick list would include double and float, and may include int (with proper bounds checking) and complex (assuming it can handle the range).

    转换/强制转换:确定您的大型int类应该转换为什么类型/类,以及如何正确地处理转换。一个快速列表将包含double和float,并且可能包含int(带有适当的边界检查)和complex(假设它可以处理范围)。

#2


40  

A fun challenge. :)

一个有趣的挑战。:)

I assume that you want integers of arbitrary length. I suggest the following approach:

我假设你想要任意长度的整数。我建议以下方法:

Consider the binary nature of the datatype "int". Think about using simple binary operations to emulate what the circuits in your CPU do when they add things. In case you are interested more in-depth, consider reading this wikipedia article on half-adders and full-adders. You'll be doing something similar to that, but you can go down as low level as that - but being lazy, I thought I'd just forego and find a even simpler solution.

考虑数据类型“int”的二进制性质。考虑使用简单的二进制操作来模拟CPU中的电路在添加东西时所做的事情。如果你有更深入的兴趣,可以考虑阅读这篇关于半加法器和全加法器的*文章。你将会做一些类似的事情,但是你可以降低到那样低的水平——但是由于懒惰,我认为我应该放弃去寻找一个更简单的解决方案。

But before going into any algorithmic details about adding, subtracting, multiplying, let's find some data structure. A simple way, is of course, to store things in a std::vector.

但是在讨论任何关于加、减、乘的算法细节之前,让我们先找到一些数据结构。当然,一种简单的方法是将东西存储在std::vector中。

template< class BaseType >
class BigInt
{
typedef typename BaseType BT;
protected: std::vector< BaseType > value_;
};

You might want to consider if you want to make the vector of a fixed size and if to preallocate it. Reason being that for diverse operations, you will have to go through each element of the vector - O(n). You might want to know offhand how complex an operation is going to be and a fixed n does just that.

您可能需要考虑是否要使向量具有固定的大小,以及是否预先分配它。因为对于不同的运算,你需要遍历向量的每个元素O(n)你可能想知道一个操作会有多复杂,一个固定的n会这样。

But now to some algorithms on operating on the numbers. You could do it on a logic-level, but we'll use that magic CPU power to calculate results. But what we'll take over from the logic-illustration of Half- and FullAdders is the way it deals with carries. As an example, consider how you'd implement the += operator. For each number in BigInt<>::value_, you'd add those and see if the result produces some form of carry. We won't be doing it bit-wise, but rely on the nature of our BaseType (be it long or int or short or whatever): it overflows.

但是现在来看看一些关于数字运算的算法。您可以在逻辑级别上完成,但是我们将使用这种神奇的CPU能力来计算结果。但是,我们将从“半边倒”和“富勒德”的逻辑阐释中接手,这是它处理“携带”的方式。例如,考虑如何实现+=运算符。对于BigInt<>: value_中的每个数字,您应该添加它们,看看结果是否产生某种形式的进位。我们不会把它做得很好,但要依赖于我们的基类型的性质(不管是长或短或短或其他):它会溢出。

Surely, if you add two numbers, the result must be greater than the greater one of those numbers, right? If it's not, then the result overflowed.

当然,如果你把两个数相加,结果一定大于其中一个数,对吧?如果不是,结果就会溢出。

template< class BaseType >
BigInt< BaseType >& BigInt< BaseType >::operator += (BigInt< BaseType > const& operand)
{
  BT count, carry = 0;
  for (count = 0; count < std::max(value_.size(), operand.value_.size(); count++)
  {
    BT op0 = count < value_.size() ? value_.at(count) : 0, 
       op1 = count < operand.value_.size() ? operand.value_.at(count) : 0;
    BT digits_result = op0 + op1 + carry;
    if (digits_result-carry < std::max(op0, op1)
    {
      BT carry_old = carry;
      carry = digits_result;
      digits_result = (op0 + op1 + carry) >> sizeof(BT)*8; // NOTE [1]
    }
    else carry = 0;
  }

  return *this;
}
// NOTE 1: I did not test this code. And I am not sure if this will work; if it does
//         not, then you must restrict BaseType to be the second biggest type 
//         available, i.e. a 32-bit int when you have a 64-bit long. Then use
//         a temporary or a cast to the mightier type and retrieve the upper bits. 
//         Or you do it bitwise. ;-)

The other arithmetic operation go analogous. Heck, you could even use the stl-functors std::plus and std::minus, std::times and std::divides, ..., but mind the carry. :) You can also implement multiplication and division by using your plus and minus operators, but that's very slow, because that would recalculate results you already calculated in prior calls to plus and minus in each iteration. There are a lot of good algorithms out there for this simple task, use wikipedia or the web.

另一种算术运算是类似的。见鬼,你甚至可以使用stl函数std::plus和std:: -, std::times和std: divide,…,但小心搬运。你也可以使用正负运算符来实现乘法和除法,但这是非常慢的,因为这将重新计算你在每次迭代中已经计算过的加减运算结果。对于这个简单的任务,有很多很好的算法,使用*或者网络。

And of course, you should implement standard operators such as operator<< (just shift each value in value_ to the left for n bits, starting at the value_.size()-1... oh and remember the carry :), operator< - you can even optimize a little here, checking the rough number of digits with size() first. And so on. Then make your class useful, by befriendig std::ostream operator<<.

当然,您应该实现诸如运算符<<(只是将value_中的每个值转换为n位的值,从value_.size()-1开始)。哦,记住进位:),运算符< -你甚至可以在这里优化一下,首先检查大小为()的数字的粗略数目。等等。然后使用befriendig std::ostream operator<。

Hope this approach is helpful!

希望这个方法能有所帮助!

#3


25  

There's a complete section on this: [The Art of Computer Programming, vol.2: Seminumerical Algorithms, section 4.3 Multiple Precision Arithmetic, pp. 265-318 (ed.3)]. You may find other interesting material in Chapter 4, Arithmetic.

关于这一点有一个完整的部分:[计算机程序设计的艺术,vol.2: Seminumerical算法,第4.3节多重精度算法,第265-318页(.3)]。你可以在第四章算术中找到其他有趣的材料。

If you really don't want to look at another implementation, have you considered what it is you are out to learn? There are innumerable mistakes to be made and uncovering those is instructive and also dangerous. There are also challenges in identifying important computational economies and having appropriate storage structures for avoiding serious performance problems.

如果您真的不想查看另一个实现,您是否考虑过要学习什么?我们要犯无数的错误,发现这些错误是有益的,也是危险的。在识别重要的计算经济和拥有适当的存储结构以避免严重的性能问题方面也存在挑战。

A Challenge Question for you: How do you intend to test your implementation and how do you propose to demonstrate that it's arithmetic is correct?

您面临的一个挑战是:您打算如何测试您的实现,以及您打算如何证明它的算术是正确的?

You might want another implementation to test against (without looking at how it does it), but it will take more than that to be able to generalize without expecting an excrutiating level of testing. Don't forget to consider failure modes (out of memory problems, out of stack, running too long, etc.).

您可能希望对另一个实现进行测试(而不考虑它是如何进行测试的),但是要想在不需要极度苛刻的测试级别的情况下进行归纳,还需要做更多的工作。不要忘记考虑失败模式(内存问题、堆栈之外、运行时间太长等等)。

Have fun!

玩得开心!

#4


6  

addition would probably have to be done in the standard linear time algorithm
but for multiplication you could try http://en.wikipedia.org/wiki/Karatsuba_algorithm

在标准线性时间算法中,可能需要做加法,但是对于乘法,可以尝试http://en.wikipedia.org/wiki/Karatsuba_algorithm

#5


5  

Once you have the digits of the number in an array, you can do addition and multiplication exactly as you would do them longhand.

一旦你在数组中有了数字,你就可以做加法和乘法,就像你长时间做一样。

#6


4  

Don't forget that you don't need to restrict yourself to 0-9 as digits, i.e. use bytes as digits (0-255) and you can still do long hand arithmetic the same as you would for decimal digits. You could even use an array of long.

不要忘记,您不需要将自己限制为0-9作为数字,也就是说,使用字节作为数字(0-255),并且您仍然可以像处理十进制数字那样做长手算术。你甚至可以使用一个长数组。

#7


3  

I'm not convinced using a string is the right way to go -- though I've never written code myself, I think that using an array of a base numeric type might be a better solution. The idea is that you'd simply extend what you've already got the same way the CPU extends a single bit into an integer.

我不相信使用字符串是正确的方法——尽管我自己从来没有编写过代码,但我认为使用基本数字类型的数组可能是更好的解决方案。其思想是,您只需将已经获得的内容扩展到CPU将单个位扩展为整数的方法。

For example, if you have a structure

例如,如果你有一个结构。

typedef struct {
    int high, low;
} BiggerInt;

You can then manually perform native operations on each of the "digits" (high and low, in this case), being mindful of overflow conditions:

然后,您可以手工对每个“数字”(在本例中为高或低)执行本机操作,注意溢出条件:

BiggerInt add( const BiggerInt *lhs, const BiggerInt *rhs ) {
    BiggerInt ret;

    /* Ideally, you'd want a better way to check for overflow conditions */
    if ( rhs->high < INT_MAX - lhs->high ) {
        /* With a variable-length (a real) BigInt, you'd allocate some more room here */
    }

    ret.high = lhs->high + rhs->high;

    if ( rhs->low < INT_MAX - lhs->low ) {
        /* No overflow */
        ret.low = lhs->low + rhs->low;
    }
    else {
        /* Overflow */
        ret.high += 1;
        ret.low = lhs->low - ( INT_MAX - rhs->low ); /* Right? */
    }

    return ret;
}

It's a bit of a simplistic example, but it should be fairly obvious how to extend to a structure that had a variable number of whatever base numeric class you're using.

这是一个有点简单的例子,但是很明显,如何扩展到具有任意基数值类的可变数量的结构。

#8


2  

Like others said, do it to old fashioned long-hand way, but stay away from doing this all in base 10. I'd suggest doing it all in base 65536, and storing things in an array of longs.

就像其他人说的,用老办法做,但是不要在10垒上做这些。我建议在65536的基础上做所有的事情,并把东西存储在一个长数组中。

#9


2  

Take a look here to see how GMP implements its algorithms.

看看GMP是如何实现它的算法的。

#10


1  

If your target architecture supports BCD (binary coded decimal) representation of numbers, you can get some hardware support for the longhand multiplication/addition that you need to do. Getting the compiler to emit BCD instruction is something you'll have to read up on...

如果您的目标体系结构支持BCD(二进制编码的十进制)数字表示,那么您可以获得一些硬件支持,以支持您需要进行的longhand乘法/加法。让编译器发出BCD指令是你必须阅读的东西……

The Motorola 68K series chips had this. Not that I'm bitter or anything.

摩托罗拉68K系列芯片就有这个功能。并不是说我很痛苦。

#11


0  

Use the algorithms you learned in 1st through 4th grade.
Start with the ones column, then the tens, and so forth.

使用你在一年级到四年级学到的算法。从一列开始,然后是十位,以此类推。

#12


0  

My start would be to have an arbitrary sized array of integers, using 31 bits and the 32n'd as overflow.

我的开始是有一个任意大小的整数数组,使用31位和32n的作为溢出。

The starter op would be ADD, and then, MAKE-NEGATIVE, using 2's complement. After that, subtraction flows trivially, and once you have add/sub, everything else is doable.

开始的操作是添加,然后,用2的补码。在那之后,减法就变得简单了,一旦你有了add/sub,其他的都是可行的。

There are probably more sophisticated approaches. But this would be the naive approach from digital logic.

可能还有更复杂的方法。但这将是数字逻辑的幼稚方法。

#13


0  

Could try implementing something like this:

可以尝试实现以下内容:

http://www.docjar.org/html/api/java/math/BigInteger.java.html

http://www.docjar.org/html/api/java/math/BigInteger.java.html

You'd only need 4 bits for a single digit 0 - 9

一个0 - 9位只需要4位

So an Int Value would allow up to 8 digits each. I decided i'd stick with an array of chars so i use double the memory but for me it's only being used 1 time.

所以一个Int值最多允许有8位数字。我决定使用一组字符,所以我用了两倍的内存,但对我来说,它只用了1次。

Also when storing all the digits in a single int it over-complicates it and if anything it may even slow it down.

同时,当将所有的数字存储在一个整数中时,它会使它变得过于复杂,甚至可能会减慢它的速度。

I don't have any speed tests but looking at the java version of BigInteger it seems like it's doing an awful lot of work.

我没有任何速度测试,但是看看java版本的BigInteger,它似乎做了很多工作。

For me I do the below

对于我,我做下面的

//Number = 100,000.00, Number Digits = 32, Decimal Digits = 2.
BigDecimal *decimal = new BigDecimal("100000.00", 32, 2);
decimal += "1000.99";
cout << decimal->GetValue(0x1 | 0x2) << endl; //Format and show decimals.
//Prints: 101,000.99

#14


-1  

subtract 48 from your string of integer and print to get number of large digit. then perform the basic mathematical operation . otherwise i will provide complete solution.

从您的整数字符串中减去48,然后打印以获得大数字。然后进行基本的数学运算。否则我会提供完整的解决方案。

#15


-1  

C++ class BigInt that enables the user to work with arbitrary precision integers. http://sourceforge.net/projects/cpp-bigint/

c++类BigInt,允许用户处理任意精度的整数。http://sourceforge.net/projects/cpp-bigint/