Мне нужно вычислить что-то вроде этого (псевдокод):
// a, b, x, y are long, x,y <= 10^12
long i = (a - n)/(x*y)
и
long j = (b - n)/(x*y) - ceiling
Иногда x * y не умещается долго. Я бы хотел избежать использования BigDecimal / BigInteger, поскольку это слишком дорого и больше нигде не нужно. Есть ли умное математическое решение, например с двумя лонгами или что-то в этом роде?
Спасибо!
ОБНОВИТЬ: Извините, ребята, еще одно ограничение: у меня также есть переменная, вычисляемая следующим образом (может быть, ее тоже можно переписать):
sum += x*y
Мне нужно пересчитать его для сравнения с другой переменной, чтобы остановить цикл.




Вы можете разделить два раза
y = a / (b * c)
y1 = a / b
y = y1 / c
Трудно понять, как именно вы используете этот sum и как рассчитывается сравниваемое значение, но можно ли вместо этого сохранить результат сравнения, чтобы избежать больших значений, например, если result> 0, то sum больше, если результат <0, то другое значение больше, ...
кажется разумным, но мне также нужно сохранить текущую сумму таких m*w, извините, я обновил вопрос
Я заметил, что значение, с которым я сравниваю sum, длинное. Итак, я решил проблему следующим образом:
i так: (long) (((a - n) / (double) x) / y))j: (long) Math.ceil ((b - n) / (double) x * y)Приведенный выше случай, конечно, переполнен. Но я предотвращаю переполнение, выполняя следующую попытку:
try {
xy = Math.multiplyExact(x, y);
...
} catch (ArithmeticException ex) {
// some handling
break;
}
Этот трюк, сделанный с помощью кода, работает достаточно быстро.
Надеюсь, это кому-то поможет!
Комментарии не подлежат расширенному обсуждению; этот разговор был переехал в чат.