+ Reply to Thread
Results 1 to 6 of 6

Thread: Big Number Representations

  1. #1
    ReignInChaos's Avatar
    ReignInChaos is offline Learning Programmer
    Join Date
    Feb 2009
    Location
    NJ
    Posts
    46
    Blog Entries
    5
    Rep Power
    12

    Arrow Big Number Representations

    Note: Although Java comes with Big Number Representations, this is an insight on how it implemented behind the scenes.

    Every computer comes with limitations and the one limitation is memory. How much "stuff" and data a computer can store and remember. Primitive data types have limitations in themselves also. For example, an int has a max value of 2(32) -1 and this goes for every data type. But what if there was an abstract data type that could rely on the limitations of the language and not the OS. In this case, an integer representation that is actually a list of integers. The largest 'int' would be 9 or 1001. We have just increased the max value without overflow. Heres some code:

    Code:
    public class BigNum {
        private List <Integer> digits;  // each digit 0..9
        private static final BigNum ZERO = new BigNum(0);
        private static final BigNum ONE = new BigNum(1);
        /**
         *
         */
        public BigNum()
        {
             digits = new LinkedList <Integer> ();
        }
        /**
         *
         * @param n The integer to be converted into a BigNum
         */
        public BigNum (int n)
       {
            this();
        if (n==0)
            digits.add (0);
    
        while (n>0)
          {
            digits.add (n % 10);    // low order digit
            n = n/10;
          }
         //size = digits.size();        //obsolete
         //this.normalize();
      }
        /**
         *
         * @param s The string to be converted into a BigNum
         */
      public BigNum(String s)
      {
          this();
          if(s.length() != 0) {
            for(int i = s.length()-1;i>=0;i--)
            {
                 digits.add(s.charAt(i) - '0');
            }
          }
      }
    These contructors take a value and store it as its respective BigNum. One interesting point to make is that negative numbers must be accounted for. This accomplished by making each BigNum a ten's complement. The reason for this is because when an int or other number type is stored, it is converted into memory as a two's compelement version. Most computers cannot directly associate a '-' as a negative number like humans do. I say most because it can be shown that a computer could understand '-' as negative but I haven't seen or heard of one before.
    Code:
        /**
        * Negate this BigNum, and return the result.  Written by (sdb)
        * @return the negated BigNum value
        */
        private BigNum negate() {
            BigNum result = new BigNum();
            boolean nonZero = false;
    
            // copy zeroes
            Iterator<Integer> it = digits.iterator();
            int d = it.next();
    
            if (!it.hasNext() && d == 0) {
                result.digits.add(0);
            }
            while (it.hasNext() && d == 0) {
                result.digits.add(d);
                d = it.next();
            }
    
            // subtract first nonzero digit from 10
            if (d != 0) {
                result.digits.add(10 - d);
    
            // subtract all other digits from 9
            }
            while (it.hasNext()) {
                d = it.next();
                result.digits.add(9 - d);
                nonZero = true;
            }
    
            // check for overflow
            if (!nonZero && d == 5) {
                result.digits.add(0);
            }
            return result;
        }
    Using a boolean method to find out if a BigNum is negative will aid in arithmetic.

    Code:
        /**
         * Checks if a BigNum is negative
         * @return true if negative. false if not
         */
        private boolean isNeg() {
            if (this.digits.get(this.digits.size() - 1) > 4) {
                return true;
            } else {
                return false;
            }
        }
    Finally, we have a full implementation of an arbitrary precision integer. This is especially important in fields that deal with very large or small numbers. For instance, NASA or mircobiologists would find this extremely useful.

    Adding is simple because all that is needed is to iterate over the list and account for carry's. However, say you add 0001 and 982374982734, the size is different therefore, the smaller BigNum needs to propigated to be the same size as the bigger one. Also, overflow does need to be accounted for and is checked after the addition has occured.

    Code:
        /**
         * Adds two BigNum numbers.
         * @param rSide
         * @return The answer after the addition
         */
        public BigNum add(BigNum num) {
            BigNum ans = new BigNum();
            int carry = 0;                   //carry value
            int sum = 0;                     //sum value
            //propigates if this is bigger
            if (this.digits.size() > num.digits.size()) {
                //n is the smaller number
                if (num.isNeg()) {
                    num.digits.add(9);
                } else {
                    num.digits.add(0);
                }
            }
            //propigates if num is bigger
            if (this.digits.size() < num.digits.size()) {
                //this is the smaller number
                if (this.isNeg()) {
                    this.digits.add(9);
                } else {
                    this.digits.add(0);
                }
            }
            //Left side iterator
            Iterator<Integer> itL = this.digits.listIterator();
            //Right side iterator
            Iterator<Integer> itR = num.digits.listIterator();
            //standard addition algorithm
            while (itL.hasNext() && itR.hasNext()) {
                sum = itL.next() + itR.next() + carry;
                carry = sum / 10;
                sum = sum % 10;
                ans.digits.add(sum);
            }
            while (itL.hasNext()) {
                sum = itL.next() + carry;
                carry = sum / 10;
                sum = sum % 10;
                ans.digits.add(sum);
            }
            while (itR.hasNext()) {
                sum = itR.next() + carry;
                carry = sum / 10;
                sum = sum % 10;
                ans.digits.add(sum);
            }
            //adding two positive numbers
            if (!this.isNeg() && !num.isNeg()) {
                ans.digits.add(0);
            }
            //adding two negative numbers
            if (this.isNeg() && num.isNeg()) {
                ans.digits.add(9);
            }
            //overflow check
            if (ans.isNeg()) {
                ans.digits.add(9);
            }
            return ans;
        }
    Other functionality can be created once the basic concept is complete and I will leave that up to you to decide to expand. I can't give away all my secrets.

  2. CODECALL Circuit advertisement
    Join Date
    Always
    Location
    Advertising world
    Posts
    Many

     
  3. #2
    Jordan Guest

    Re: Big Number Representations

    Very nice tutorial, +rep.

  4. #3
    Join Date
    Jul 2006
    Posts
    16,491
    Blog Entries
    75
    Rep Power
    143

    Re: Big Number Representations

    +rep. I've been using GMP with the ProjectEuler problems because many of the calculations exceed unsigned long int. I'm glad Java has something similar.
    Programming is a branch of mathematics.
    My CodeCall Blog | My Personal Blog

  5. #4
    drdebcol's Avatar
    drdebcol is offline Newbie
    Join Date
    Jun 2009
    Location
    Kernel Memory
    Posts
    3
    Rep Power
    0

    Re: Big Number Representations

    Yeah, the best way of declaring big number is by using an array of digits where first number is the heaviest and the last number is the easiest.
    It is interesting how you made that. I was making the same algorithm in Delphi some time ago and i had the same problem with length. I am a perfectionist and i wanted to make it like for real numbers (14312,1243124) with "," and i made it for addition, but it was heavy for division.

  6. #5
    Join Date
    May 2008
    Location
    Hell
    Posts
    3,852
    Blog Entries
    4
    Rep Power
    49

    Re: Big Number Representations

    Cool !

  7. #6
    Join Date
    Jul 2006
    Posts
    16,491
    Blog Entries
    75
    Rep Power
    143

    Re: Big Number Representations

    Every time I've thought about creating a custom big-int class, I've thought in terms of an array of ints. You can use modulus and integer division to shift half the int to the next (higher) term in the array. The advantage would be that you don't have to worry about reimplementing a lot of the logic of arithmetic.
    Programming is a branch of mathematics.
    My CodeCall Blog | My Personal Blog

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Number with zero
    By lol33d in forum PHP Development
    Replies: 4
    Last Post: 04-21-2011, 01:42 AM
  2. Very big number?
    By Hamed in forum C and C++
    Replies: 35
    Last Post: 12-16-2010, 10:00 AM
  3. PHP: only number
    By usmanzm in forum Classes and Code Snippets
    Replies: 2
    Last Post: 08-22-2008, 09:10 AM
  4. NaN - Not a Number
    By funkey_monkey in forum General Programming
    Replies: 0
    Last Post: 03-31-2008, 07:44 AM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts