Методы, реализующие операции умножения, вычитания и деления целых чисел, используя только оператор суммирования

В этой задаче можно использовать только сложение. В подобных задачах полезно вспомнить суть математических операций и как их можно реализовать с помощью сложения (или других операций).

Вычитание

Как реализовать вычитание с помощью сложения? Это предельно просто. Операция a – b –  то же самое, что и a + (-1) * b. Посколько мы не можем использовать оператор умножения, нам придется создать функцию negate.

public static int negate(int a) {
    int neg = 0;
    int d = a < 0 ? 1 : -1;
    while (a != 0) {
        neg += d;
        a += d;
    }
    return neg;
}

public static int subtract(int a, int b) { 
    return a + negate(b);
}

Отрицательное значение k получается суммированием k раз числа -1.

Умножение

Связь между сложением и умножением тоже достаточно очевидна. Чтобы перемножить a и b, нужно сложить значение a с самим собой b раз.

public static int multiply(int a, int b) {
    if (a < b) {
        return multiply(b, a); // алгоритм будет быстрее, если b < a
    }
    int sum = 0;
    for (int i = abs(b); i > 0; i--) {
        sum += a;
    }
    if (b < 0) {
        sum = negate(sum);
    }
    return sum;
}

public static int abs(int a) {
    if (a < 0) {
        return negate(a);
    } else {
        return a;
    }
}

При умножении нам нужно обратить особое внимание на отрицательные числа. Если b – отрицательное число, то необходимо учесть знак суммы:

multiply(a, b) < – abs(b) * a * (-1 if b < 0).

Кроме того, для решения это задачи мы создали простую функцию abs.

Деление

Самая сложная из математических операций – деление. Хорошая идея – использовать для реализации метода divide методы multiply, subtract и negate.

Нам нужно найти x, если x = a / b. Давайте переформулируем задачу: найти x, если a = bx. Теперь мы изменили условие так, чтобы задачу можно было решить с помощью уже известной нам операции – умножения.

Обратите внимание, что можно вычислить x как результат суммирования b, пока не будет получено a. Количество экземпляров b, необходимых, чтобы получить a, и будет искомой величиной x.

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

Приведенный ниже код реализует данный алгоритм:

public int divide(int a, int b) 
throws java.lang.ArithmeticException {
    if ( b == 0) {
        throw new java.lang.ArithmeticException("ERROR");
    }
    int absa = abs(a);
    int absb = abs(b);

    int product = 0;
    int x = 0;
    while (product + absb <= absa) {
        product += absb;
        x++;
    }
    
    if ((a < 0 && b < 0) || (a > 0 && b > 0)) {
        return x;
    } else {
        return negate(x);
    }
}

Разбор взят из перевода книги Г. Лакман Макдауэлл и предназначен исключительно для ознакомления.
Если он вам понравился, то рекомендуем купить книгу «Карьера программиста. Как устроиться на работу в Google, Microsoft или другую ведущую IT-компанию».