Есть ли способ избежать BigInteger / BigDecimal? - PullRequest
0 голосов
/ 03 января 2019

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

// a, b, x, y are long, x,y <= 10^12

long i = (a - n)/(x*y)

и

long j = (b - n)/(x*y) - ceiling

Иногда х * у долго не помещается. Я хотел бы избежать использования BigDecimal / BigInteger, так как это слишком дорого и больше нигде не нужно. Есть ли умное математическое решение, например с двумя длинными или что-то в этом роде?

Спасибо!

ОБНОВЛЕНИЕ : Извините, ребята, еще одно ограничение: у меня также есть переменная, вычисленная следующим образом (может быть, она также может быть переписана):

sum += x*y

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

Ответы [ 2 ]

0 голосов
/ 04 января 2019

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

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

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

0 голосов
/ 03 января 2019

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

y = a / (b * c) 

y1 = a / b

y = y1 / c

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

...