13

I'm messing around with writing a class similar to mpz (C) or BigInteger (Java). This is just for fun, so please don't go on about how I shouldn't be writing my own.

I have a class similar to:

public class HugeInt
{
    public List<Integer> digits;

    public HugeInt(String value)
    {
        // convert string value into its seperate digits. 
        // store them in instance variable above
    }
}

Now, doing the add() and subtract() method of this class are pretty simple. Here is an example:

private List<Integer> add(List<Integer> a, List<Integer> b)
    {
        List<Integer> smallerDigits = (compareDigits(a,b) < 0) ? a : b;
        List<Integer> largerDigits = (compareDigits(a,b) >= 0) ? a : b;
        List<Integer> result = new ArrayList<Integer>();

        int carry = 0;

        for(int i = 0; i < largerDigits.size(); i++)
        {
            int num1 = largerDigits.get(i);
            int num2 = (i < smallerDigits.size()) ? smallerDigits.get(i) : 0;

            result.add((num1 + num2 + carry) % 10);
            carry = ((num1 + num2 + carry) / 10);
        }

        if (carry != 0) result.add(carry);

        return result;
    }

Similarly, doing the multiply wasn't that hard either.

I see on wikipedia there is a page on Division Algorithms, but I'm not sure which one is appropriate for what I'm trying to do.

Because these positive integers (represented as digits) can be arbitrarily long, I want to make sure I don't attempt to do any operations on anything other than digit-by-digit basis.

However, can anyone point me in the right direction for doing a division of two numbers that are represented as List<Integer>'s? Also, I can ignore the remainder as this is integer division.

Mithrax
  • 7,603
  • 18
  • 55
  • 60

4 Answers4

5

You could just do long division, but this certainly isn't the optimal way to do it (edit: although it seems that something like this is a good way to do it). You could look at other implementations of big integer libraries, and a bit of Googling turns up a fair bit of useful information.

David Johnstone
  • 24,300
  • 14
  • 68
  • 71
  • 2
    Actually, the paper-and-pencil long division method is fairly close to the way many big integer division algorithms work for common sizes. To oversimply greatly, you use a small number of leading digits to estimate a quotient digit, then compute the partial remainder and repeat. You need to detect when your estimate is wrong and recover from it. – President James K. Polk Feb 27 '10 at 01:33
2

This may be a slight overkill, but if this is the kind of things you do for fun, you'll enjoy reading this: http://www.fizyka.umk.pl/nrbook/c20-6.pdf (that's "Arithmetic at Arbitrary Precision" from "Numerical recipes in C"). Pretty fascinating, as is most of this book, with good explanations and lots of code.

AVB
  • 3,994
  • 22
  • 21
0

Since I assume you're just dealing with integer division it's not very hard. Multiplication is repeated addition, division is the opposite - repeated subtraction. So what you'll do is check how many times you can subtract the divisor from the dividend. For example, 3 can be subtracted from 10 3 times without going <0, so the integer division quotient is 3.

monoceres
  • 4,722
  • 4
  • 38
  • 63
  • That's not digit by digit, though. I think he want's to emulate long-division. – Bill K Feb 25 '10 at 23:48
  • I had considered this, but assumed that it would be terribly inefficient. Now I'm wondering if it would suffice or if like Bill K said, emulating long-division would be best. – Mithrax Feb 25 '10 at 23:50
  • @Mithrax, yes, this would be very inefficient when dividing by small numbers like 1. You would iterate N times, where N is your big integer. (And if you didn't kee your count in another big integer, you'd risk overflowing primitive integral types.) – Mike Daniels Feb 26 '10 at 00:10
  • @Mike: I've haven't thought about it in detail, but initially I don't think you need to loop through every integer individually; you can get a pretty high lower bound for the result based on the difference in the number of digits. If that difference is zero, then you only need to loop from 1 to 9. – d.. Feb 26 '10 at 00:29
  • Hmmm... On second thoughts, not sure how high "pretty high" would be, not too high is some cases it seems. – d.. Feb 26 '10 at 00:32
0

This article A Larger Integer does not show how to implement digit by digit operations for "larger integers", but it does show how to implement a (apparently fully functional) 128 bit integer in terms of two Int64 types. I would imagine that it would not be too hard to extend the approach to use an array of Int64 types to yield an arbitary length integer. I just spent a few minutes looking back over the article and the implementation of multiply looks like it could get pretty involved for arbitrary length.

The article shows how to implement division (quotient and remainder) using binary division.

wageoghe
  • 27,390
  • 13
  • 88
  • 116