Есть ли способ избежать BigInteger / BigDecimal?

Мне нужно вычислить что-то вроде этого (псевдокод):

// 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

Мне нужно пересчитать его для сравнения с другой переменной, чтобы остановить цикл.

Комментарии не подлежат расширенному обсуждению; этот разговор был переехал в чат.

Samuel Liew 04.01.2019 00:13
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
1
129
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете разделить два раза

y = a / (b * c) 

y1 = a / b

y = y1 / c

Трудно понять, как именно вы используете этот sum и как рассчитывается сравниваемое значение, но можно ли вместо этого сохранить результат сравнения, чтобы избежать больших значений, например, если result> 0, то sum больше, если результат <0, то другое значение больше, ...

кажется разумным, но мне также нужно сохранить текущую сумму таких m*w, извините, я обновил вопрос

Dmitry Senkovich 03.01.2019 09:42
Ответ принят как подходящий

Я заметил, что значение, с которым я сравниваю 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;
            }
    

Этот трюк, сделанный с помощью кода, работает достаточно быстро.

Надеюсь, это кому-то поможет!

Другие вопросы по теме