Добавление отрицательных и положительных чисел в java без BigInt

Я пытаюсь написать небольшой класс Java. У меня есть объект BigNumber. Я написал метод, который добавляет два положительных числа, и другой метод, который вычитает два положительных числа.

Теперь я хочу, чтобы они обрабатывали отрицательные числа. Итак, я написал пару утверждений «если», например.

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);
    }

и т.п.

К сожалению, код выглядит просто уродливо. Как куст если и elses. Есть ли лучший способ написать такой код?

Редактировать я не могу просто сделать this.add(sn1), потому что иногда я хочу добавить положительное число к отрицательному или отрицательное к отрицательному. Но add может обрабатывать только положительные числа. Поэтому я должен использовать базовую математику и, например: вместо добавления отрицательного числа к отрицательному числу я добавляю this.abs() (абсолютное значение числа) к sn1.abs() и возвращаю результат с противоположным знаком. Дрю: это строки из метода _add. Я использую этот метод, чтобы решить, что делать с полученными числами. Отправить их, чтобы добавить метод? Или отправить их методом subract, но в другом порядке (sn1.subtract(this))? И так далее..

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();
}

Как видите, этот код выглядит ужасно.


person Community    schedule 21.01.2010    source источник
comment
Почему вы не можете просто this.add(sn1) во всех случаях?   -  person Anon.    schedule 22.01.2010
comment
Бьюсь об заклад, есть более простой способ написать это, но я думаю, что нам, вероятно, понадобится больший образец вашего кода. Из какого метода эти строки?   -  person Drew Wills    schedule 22.01.2010
comment
я не могу просто сделать это. add (sn1), потому что иногда я хочу добавить положительное число к отрицательному или отрицательное к отрицательному. Но add может обрабатывать только положительные числа. Поэтому я должен использовать базовую математику и, например: вместо добавления отрицательного числа к отрицательному числу я добавляю this.abs() (абсолютное значение числа) к sn1.abs() и возвращаю результат с противоположным знаком. Дрю: это строки из метода _add. Я использую этот метод, чтобы решить, что делать с полученными числами. Отправить их, чтобы добавить метод? Или отправить их методом вычитания, но в другом порядке (sn1.subtract(this))? И так далее..   -  person    schedule 22.01.2010
comment
Кстати, вы можете посмотреть исходный код Java BigInteger. Кроме того, вы можете просто использовать его.   -  person notnoop    schedule 22.01.2010
comment
Я уже читал код BigInteger, но он выглядит слишком сложным для такого новичка, как я.   -  person    schedule 22.01.2010


Ответы (4)


Предлагаю провести еще несколько способов ;) Как насчет этого:

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

Обратите внимание, что я переименовал sn1 в other, а метод add в plus, чтобы указать, что метод возвращает сумму для повышения удобочитаемости. add обычно используется, если что-то добавляется к самому объекту (как в классе BigInteger).

Реализации для isPositive и isBiggerThen довольно просты:

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

private boolean isBiggerThen(BigNumber other) {
  return this.compare(other) > 0;
}
person Andreas Dolk    schedule 21.01.2010
comment
Спасибо - это выглядит намного лучше. Но есть ли способ удалить большинство «если»? - person ; 22.01.2010
comment
Если полностью переписать: возможно. Но попробуйте выделить все больше и больше кода в отдельные методы. Это значительно улучшает читабельность, и вам не нужно использовать множество конструкций if-else в одном методе. Если это просто для улучшения ваших навыков - продолжайте начатое :) - person Andreas Dolk; 22.01.2010

Вы можете рассмотреть возможность использования арифметики с дополнением до двух. Это значительно упростило бы сложение и вычитание. Не нужно беспокоиться о знаковых битах, просто сложите числа.

person President James K. Polk    schedule 22.01.2010
comment
+1 за это. Написание метода add() для обработки только значений с одинаковым знаком — первая ошибка liamg. Сложение и вычитание на самом деле должны быть одним и тем же действием, как и при подходе комплимента двойки. - person Matthew Flynn; 22.01.2010
comment
Спасибо за ответы. Я думал об использовании двоичных чисел, но это выглядело слишком «низкоуровневым» для моей цели. Но я никогда не слышал об арифметике с дополнением, думаю, она пригодится мне в будущем. - person ; 22.01.2010

Что-то вроде этого может быть более привлекательным:

if (this.sign == 1 && sn1.sign == 1) {
    return (this.compare(sn1) < 0) ? sn1.add(this) : this.add(sn1);
}
person Mark Elliot    schedule 21.01.2010

Пара вещей сбивает меня с толку. Не следует добавлять коммутативно. то есть он должен давать тот же результат для a + b, что и b + a.

В большинстве случаев вам просто нужно определить, совпадает ли знак, чтобы добавить абсолютные значения.

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);
person Peter Lawrey    schedule 11.05.2010