The professional, friendly Java community. 21,500 members and growing!

The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.

Please Review My Code (Long Integer Addition)

Hello everyone, thought I'd join up as this looks like a good, popular java programming community and a place to learn new things.

I am currently doing a summer research project on the implementation and verification of long integer arithmetic (some may know it as arbitrary-precision arithmetic or bignum). There will be four programs altogether: Addition, subtraction, naive multiplication and karatsuba multiplication.

I have completed the long integer addition program using what our tutor has recommended (convert user input values into an integer array, then perform addition on a units, tens, hundreds, etc basis taking into account carried numbers; like you would do addition in school.)

The result I believe is pretty decent, the program I've made can perform addition of two 50,000 digit numbers and print the solution to a text file in about 3-4 seconds.

My reason for posting it here is so that you can all take a look at the code, review it and make suggestions on improvements and how to increase efficiency (if there is a need to do so).

Obviously if you believe there is a way I can improve the code, I would like to hear merely a hint or a suggestion of a topic/class/method to research as opposed to flat-out typing said improved code.

I look forward to hearing your comments! The code is below:

/**************************************************
* LongIntAdd.java - Program which takes in two
* long integers and performs an add operation on
* them by converting to arrays and operating on a
* digit-by-digit basis, taking into account any
* carried digits.
*
* Execution: java LongIntAdd
* Input: [Value 1] [Value 2]
* Runtime: Two 50000-digit numbers take roughly
* 3.5 seconds to add together.
*************************************************/
// Package import declarations.
import java.util.Scanner;
import java.io.*;
import static java.lang.Math.*;
public class LongIntAdd {
public static void main(String args[]) {
try {
// Scanner class takes user input [Value 1] [Value 2] and stores
// as v1 and v2.
Scanner in = new Scanner(System.in);
String v1 = in.next();
String v2 = in.next();
// Initialize and declare variables (c is the carried number).
int vs1 = v1.length();
int vs2 = v2.length();
int vMax = max(vs1,vs2);
int vMin = min(vs1,vs2);
int[] vArray1 = new int[vMax];
int[] vArray2 = new int[vMax];
int[] sArray = new int[vMax+1];
int c = 0;
// Create int arrays from the two strings, working from right to
// left. Both arrays are the same size, so if one string is smaller
// than the other, the remaining spaces to the left are null values
// in the array (0).
for(int i = 1; i <= vs1; i++){
vArray1[vMax-i] = Integer.parseInt(v1.substring(vs1-i,vs1-i+1));
}
for(int i = 1; i <= vs2; i++){
vArray2[vMax-i] = Integer.parseInt(v2.substring(vs2-i,vs2-i+1));
}
// Create solution int array by adding together the digits for the
// two value arrays from right to left, taking into account the carried
// value. If there is a carry, c is assigned 1 and the array index has
// 10 taken away to ensure it only has units and not the tens which is
// carried. Otherwise, the carry is assigned 0.
for(int i = vMax; i >= 1; i--){
sArray[i] = vArray1[i-1] + vArray2[i-1] + c;
if (sArray[i] > 9) {
c=1;
sArray[i]=sArray[i]-10;
}
else {
c=0;
}
}
// The first index in the solution array is simply the carry value, whether
// it be 0 or 1.
sArray[0] = c;
// Converts the solution int array back into a string and writes it to a text
// file. Checks to see whether the first digit is 0 (in other words, there
// was no carry from the final addition). If so, it is ignored; else, it is
// kept.
BufferedWriter out = new BufferedWriter(new FileWriter("LongIntAdditionSolution.txt"));
int nullCheck = 0;
if (sArray[0] == 0) {
nullCheck = 1;
}
for (int i = nullCheck; i < sArray.length; i++) {
out.write(Integer.toString(sArray[i]));
}
out.close();
}
catch (IOException e) {
System.err.println("There has been an error!");
e.printStackTrace();
}
}
}

Oh and I'm all for good programming practice, so if there's anything here that may be bad practice, please tell me and suggest improvements for them!

Re: Please Review My Code (Long Integer Addition)

The only thin i would change after a first look is main methods generally shouldn't throw checked exceptions. Not really a problem compile wise, but if there is a checked exception, it usually should be handled by your program and not the JVM (even if all you do is simply catch and ignore it). You could change your program by simply moving the "try" statement to the top of the method and removing the "throws" declaration.

I'm curious to know why you have the "//s" delimiter... That's done by the next() method (correct me if i'm wrong someone).

All in all, this is a nice piece of code. I don't see a way to optimize this substantially, though it would be easier to read if you used the charAt() method instead of the substring() method to read each individual number in.

The Following User Says Thank You to helloworld922 For This Useful Post:

Re: Please Review My Code (Long Integer Addition)

Originally Posted by helloworld922

The only thin i would change after a first look is main methods generally shouldn't throw checked exceptions. Not really a problem compile wise, but if there is a checked exception, it usually should be handled by your program and not the JVM (even if all you do is simply catch and ignore it). You could change your program by simply moving the "try" statement to the top of the method and removing the "throws" declaration.

I'm curious to know why you have the "//s" delimiter... That's done by the next() method (correct me if i'm wrong someone).

All in all, this is a nice piece of code. I don't see a way to optimize this substantially, though it would be easier to read if you used the charAt() method instead of the substring() method to read each individual number in.

Not your first post, but welcome anyways!

Thanks for the comments! I actually added the throw in as an afterthought. I wasn't sure whether it was required or not so took a gamble. I've always been a little iffy on exceptions and errors so that's something I need to read up on. I'm glad you've cleared things up with that though!

Regarding the delimiter, you're right, I just tested without the delimiter statement and it worked, so whitespace is the default. I thought the default was newline, hence why I explicitly specified the delimiter. Thanks for bringing that up!

Using charAt(), am I right in assuming that I would need to convert the char into a string prior to parsing it into an integer? I assume that if I directly converted the char into an int I would get the ASCII code (i.e. 1 would become 49 rather than 1). If you could clarify that. Here's what I get:

Re: Please Review My Code (Long Integer Addition)

Scratch that, on another forum Character.digit() was brought up, not sure why I didn't have that in mind first time round!

Also, on the other forum, someone highlighted the fact that creating two arrays of the same size for the values could be very wasteful if, for example, one value is 50,000 digits and the other is only 1 digit! A very valid point which I had completely overlooked!!

So I've been working all night on a solution, here's what I've come up with:

Please tell me what you think. As you can see, the part of the code which creates the value arrays is much simpler, standard and more easy to read now. Also the arrays created are the same size as the values they're derived from, as opposed to being the same size and the smaller value's array being filled with null values!

The only downside with this revised code is I have duplicated the if-else statement regarding the carry number (it's in both for loops). Right now, I can't see any satisfactory way around this...

What I've done is explained in the code comments, it's the most efficient way of doing things from what I can see. I hope so anyway! It certainly deals with different sized values much more effectively.

This way, once the smaller digit value is trying to refer to negative indexes it is simply ignored (the variable is set to 0). This acts in the same way as the code in my previous post but with just one for loop, and the carry if-else statement only needs to be written once!

I think the code is pretty much sorted now, I will be grouping the different parts into their own methods once the LongIntegerSubtraction.java program is written, so that I can pass values between the two (if they're negative for example, the Add program can pass them to the Subtract program easily), but for now I don't think it's necessary.

If someone could give one last look at my code (taking into account the new code in this post) and give the OK, then I can mark this as solved! Then I'll be back in a few days so you can have a look at my Subtract program and the linking between the two!!

Thats some good optimisation there! I can't do something like this though as it's strictly stated in the project guidelines that the input values are to be converted into arrays and then addition/subtraction made on an index-by-index basis.

Re: Please Review My Code (Long Integer Addition)

But it is an array. String are just character arrays. Oh well, for an assignment better safe than sorry.

Thats true, they don't make it completely clear.... They say "represent as an array", that could mean convert, it could mean taking the string and pulling it apart as a character array.

I'll check about that, that said, since the code is above and complete, I'd feel a little guilty for just using it as is, so I'll probably stick to what I've got to avoid any guilt! (I do understand what you've put there though, apart from the counter bit you added at the end to avoid 0's at the beginning....could you explain that bit?)

Re: Please Review My Code (Long Integer Addition)

Ok, that second fragment is to solve this problem:
say, someone decided they wanted to add 000123 to 1 (kind of strange, put a legal string input)
answer without it:
"000124"
not necessarily the wrong answer, but you probably wouldn't want to do that. It just removes all the leading 0's. It stops just before the last digit, cause if that's zero, we want to leave it.

Re: Please Review My Code (Long Integer Addition)

Originally Posted by helloworld922

Ok, that second fragment is to solve this problem:
say, someone decided they wanted to add 000123 to 1 (kind of strange, put a legal string input)
answer without it:
"000124"
not necessarily the wrong answer, but you probably wouldn't want to do that. It just removes all the leading 0's. It stops just before the last digit, cause if that's zero, we want to leave it.

the for loop is just there to count up the leading zeros.

Ahh ok, that makes sense now. Thanks very much for all your help! I'll be back next week with my subtraction program for everyone to critique (or if I dont do it before wednesday, I'll be on in about 2 weeks, as I'm going to Greece for a week!).