2

I'm creating a custom implementation of Java's BigInteger class, with subsequent methods:

  • multiply
  • divide,
  • add
  • subtract.

I have a problem with division.

private BigInt createQuotient (BigInt aNumber, BigInt other){ BigInt dividend = new BigInt(aNumber.toString()); BigInt divisor = new BigInt(other.toString()); dividend.isNegative = false; divisor.isNegative = false; BigInt finalQoutient = new BigInt("0"); BigInt one = new BigInt("1"); while(compareBigInts(dividend, divisor) == 1) { BigInt two = one; BigInt lastTwo = new BigInt("0"); BigInt temp = divisor; BigInt lastTemp = new BigInt("0"); while(compareBigInts(dividend, temp) == 1) { lastTwo = two; lastTemp = temp; if (two == one) { two = two.add(one); } else{ two = two.add(two); } temp = divisor.multiply(two); } finalQoutient = finalQoutient.add(lastTwo); dividend = dividend.subtract(lastTemp); } finalQoutient = finalQoutient.add(one); return finalQoutient; } 

Code represents this algorithm:

Let's say 100 is our dividend and 5 is our divisor with 20 being our final quotient.

while dividend > divisor, do: 2^0 * 5 = 5 which is less than our dividend, so we increment two ; 2^1 * 5 = 10 which is less than our dividend, so we increment two ; 2^2 * 5 = 20 which is less than our dividend, so we increment two ; 2^3 * 5 = 40 which is less than our dividend, so we increment two ; 2^4 * 5 = 80 which is less than our dividend, so we increment two ; (lastTemp) 2^4 * 5 = 160 which is greater than our dividend, so we save the value before this one ; (temp) 

We then take that saved value and remove it from the dividend, making it smaller. We simultaneously take that value and add it to a variable each time a loop is completed.

We do this until the dividend gets to be smaller than the divisor, at which point we simply return the variable that stored added lastTemp for each loop.

With that in mind, my program works for smaller numbers but becomes extremely slow as aNumber becomes larger. Since all my variables are shrinking I would expect each pass to be faster, however my program gets slower.

Why is this?

Full BigInt class.

https://github.com/collinarnett/big-int/blob/master/BigInt.java

15
  • Do you know what is Big O notation? You have n*n Algorithm! Commented Jun 20, 2018 at 21:40
  • 1
    The inner while loop is operating on a smaller number (since dividend shrinks) each time the outer while loop is run, therefore it should run faster with each pass of the outer while loop. @Gatusko Commented Jun 20, 2018 at 21:44
  • how does compare work? When the numerator is bigger, does it return 1? Commented Jun 20, 2018 at 22:33
  • @fileyfood500 Compare returns 1 when the numerator is greater than the denominator, -1 when the denominator is greater than the numerator and 0 when they are equal. Commented Jun 20, 2018 at 22:39
  • Looking at compare, it seems like the denominator must have fewer digits than the numerator (or the same), but maybe I'm misreading something or it's not relevant here Commented Jun 20, 2018 at 22:44

1 Answer 1

2

Apparently, sizes of dividend.bigNum.size() and temp.bigNum.size() grow exponentially on each iteration. I've added

System.out.println(dividend + " " + temp + "; sizes are " + dividend.bigNum.size() + " " + temp.bigNum.size()); 

right before your innermost while loop and got the following:

366000000000 36; sizes are 12 12 56762354688 36; sizes are 24 24 18107649024 36; sizes are 48 48 8443972608 36; sizes are 96 96 3612134400 36; sizes are 192 192 1196215296 36; sizes are 384 384 592235520 36; sizes are 768 768 290245632 36; sizes are 1536 1536 139250688 36; sizes are 3072 3072 

That happens in part because your BigInt(String) does not truncate heading zeros (probably should be done in createArrayList) and in part because they're doubled by createProduct in both arguments.

My recommendation for the future is to debug this issue the same way as if it were a correctness issue: print variable sizes, look at expected sizes, look at real values. Also, you can use profiler.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes this fixed my issue. I've added a method removeZeros that I've put at the end of these methods. Thank you so much.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.