views:

377

answers:

4

Hi, i'm trying to write a small java class. I have an object called BigNumber. I wrote method that add two positive numbers, and other method that subract two also positive numbers.

Now i want them to handle negative numbers. So the i wrote couple of 'if' statements eg.

if (this.sign == 1 /* means '+' */) {
    if (sn1.sign == 1) {
        if (this.compare(sn1) == -1 /* means this < sn1 */ ) return sn1.add(this);
        else return this.add(sn1);
    }

etc.

Unfortunately the code looks just ugly. Like a bush of if's and elses. Is there a better way to write that kind of code?

Edit i can't just do this.add(sn1) beacuse sometimes i want to add positive number to negative one or negitve to negative. But add can handle only positive numbers. So i have to use basic math and for example: instead of add negative number to negative number i add this.abs() (absolute value of number) to sn1.abs() and return the result with opposite sign. Drew: this lines are from method _add. I use this method to decide what to do with numbers it receive. Send them to add method? Or send them to subract method but with different order (sn1.subtract(this))? And so on..

if (this.sign == 1) {
    if (sn1.sign == 1) {
        if (this.compare(sn1) == -1) return sn1.add(this);
        else return this.add(sn1);
    }
    else if (wl1.sign == 0) return this;
    else {
        if (this.compare(sn1.abs()) == 1) return this.subtract(sn1.abs());
        else if (this.compare(sn1.abs()) == 0) return new BigNumber(0);
        else return sn1.abs().subtract(this).negate(); // return the number with opposite sign;
    }
} else if (this.sign == 0) return sn1;
else {
    if (wl1.sign == 1) {
        if (this.abs().compare(sn1) == -1) return sn1.subtract(this.abs());
        else if (this.abs().compare(sn1) == 0) return new BigNumber(0);
        else return this.abs().subtract(sn1).negate();
    } else if (sn1.sign == 0) return this;
    else return (this.abs().add(wl1.abs())).negate();
}

As you can see - this code looks horrible..

A: 

Something like this might be more appealing:

if (this.sign == 1 && sn1.sign == 1) {
    return (this.compare(sn1) < 0) ? sn1.add(this) : this.add(sn1);
}
Mark E
A: 

I suggest you spend some more methods ;) How about this:

if (isPositive() && other.isPositive()) {
  if (this.isBiggerThen(other)) {
    return this.plus(other);
  } else {
    return other.plus(this);
  }
}

Note that I renamed sn1 to other and the add method to plus to indicate, that the method returns the sum to increase readability. add is usually used if something is added to the object itself (like in the BigInteger class).

The implementations for isPositive and isBiggerThen are pretty simple:

private boolean isPositive() {
  return sign == 1;
}

private boolean isBiggerThen(BigNumber other) {
  return this.compare(other) > 0;
}
Andreas_D
Thanks - that looks a lot more botter. But is there a way to remove most of the if's?
liamg
If you completely rewrite it: maybe. But try extracting more and more code into separate methods. That greatly improves readbility and you don't have to many if-else constructs in a single method. If it's just for improving your skills - carry on with what you started :)
Andreas_D
+1  A: 

You might consider using twos-complement arithmetic. This would considerably simplify addition and subtraction. No need to worry about sign bits, just add the numbers together.

GregS
+1 for this. Writing the add() method to only handle values with the same sign is liamg's first mistake. Addition and subtraction really should be the same activity, as they would be with a two's compliment approach.
Matthew Flynn
Thanks for answers.I was thinking about using binary numbers but it looked too 'low-level' for my purpose. But i've never heard about thos-complement arithmetic, it will be useful in my future i believe.
liamg
A: 

A couple of things baffle me. Shouldn't add is commutative. i.e. it should give the same result for a + b as b + a.

In most cases you just have to determine if the sign is the same to add the absolute values.

e.g.

if (sign == sn1.sign)
   return add(sn1);// add the absolute values and keep the sign. 1 + 1 == 2, -1 + -1 == -2
if (sign == 0) return sn1;
if (sn1.sign == 0) return this;
// you only need to know which value is larger for subtraction.
// keep the sign of the first argument and substract the absolute value.
return compare(sn1) > 0 ? substract(sn1) : sn1.substract(this);
Peter Lawrey