2016-06-11 1 views
4

У меня есть следующий код sage, который запускается мгновенно (менее секунды), и я пытаюсь преобразовать его в Java (используя встроенную библиотеку BigInteger Java). Но я не увенчался успехом.Попытка понять систему номер шага для BigInteger

Короче говоря, я инициализируется N как BigInteger и дельта в два раза, и для того, чтобы вычислить мощность (BigInteger^дважды) я преобразовал N к BigDecimal (т.е. new BigDecimal(BigInteger)), а затем:

  1. я использовал this подход, но это слишком медленно (очень медленно).
  2. Я использовал this библиотеки, но я потерял слишком много точности.
  3. Я использовал библиотеку this, но я получил исключение переполнения.

N = 16260595201356777876687102055392856230368799478725437225418970788404092751540966827614883675066492383688147288741223234174448378892794567789551235835087027626536919406320142455677084743499141155821894102610573207343199194327005172833989486958434982393556326206485954223151805798621294965926069728816780985683043030371485847746616146554612001066554175545753760388987584593091716701780398711910886679925612838955858736102229719042291682456480437908426849734556856917891628730543729446245974891735371991588505429152639045721840213451875487038496578525189542369448895368117152818687795094021869963915318643663536132393791 
delta = 0.26 
X = 2*floor(N^delta) # in sage,^operator means exponentiation 
        # similar to ** operator in python 

print("X:" + str(x)) 

Выход:

X: 32803899270297070621193977210731234596426011189989730481205367370572340252530823123935195892838208219967066426399488721710159859316222019683979411877007525412864


Что такое магия? Как мудрец это делает? Как преобразовать этот код в Java (и получить аналогичный результат), должно быть какое-то решение.

+0

По существу я хочу экспоненциируются BigInteger в два раза. –

+0

В этом случае я озадачен необходимостью точности, превышающей то, что вы могли бы получить, преобразовывая очень большое целое число в "double" и увеличивая степень с помощью 'pow()', потому что экспоненциальное отношение к нецелочисленной мощности даст иррациональное число в результате. – Steve

+0

@Steve Я попробовал (ссылка: http://pastebin.com/raw/BpGn83Sb), но я получаю бесконечность. –

ответ

2

Вы можете использовать подход №1 с обходным путем. Проблема в том, что BigFunctions.ln() не очень эффективен для чисел с большой целочисленной частью (число цифр слева от десятичной точки). В качестве обходного пути я масштабировал число так, чтобы он содержал не более одной цифры в целочисленной части и компенсировал это позже, добавив ln(10) * rescale * delta к аргументу exp().
Следует также отметить, что использование конструктора new BigDecimal(double) приводит к потере точности - для получения пояснения читайте javadoc. Вместо этого вы должны использовать new BigDecimal(String) (особенно если этот двойник поступает из какого-либо значения конфигурации) или BigDecimal.valueOf(double).

BigInteger N = new BigInteger("16260595201356777876687102055392856230368799478725437225418970788404092751540966827614883675066492383688147288741223234174448378892794567789551235835087027626536919406320142455677084743499141155821894102610573207343199194327005172833989486958434982393556326206485954223151805798621294965926069728816780985683043030371485847746616146554612001066554175545753760388987584593091716701780398711910886679925612838955858736102229719042291682456480437908426849734556856917891628730543729446245974891735371991588505429152639045721840213451875487038496578525189542369448895368117152818687795094021869963915318643663536132393791"); 
double delta = 0.26; 

// this scale is sufficient to get the exact integer part 
// it is roughly equal to the number of digits in the result's integer part 
final int SCALE = 170; 
BigDecimal x = new BigDecimal(N); 
BigDecimal y = BigDecimal.valueOf(delta); 

int maxIntDigits = 1; 
int intDigits = x.precision() - x.scale(); 
int rescale = Math.max(intDigits - maxIntDigits, 0); 
BigDecimal rescaledX = x.scaleByPowerOfTen(-rescale); 

BigDecimal z = BigFunctions.exp(
     BigFunctions.ln(rescaledX, SCALE) 
       .add(BigFunctions.ln(BigDecimal.TEN, SCALE).multiply(BigDecimal.valueOf(rescale))) 
       .multiply(y), 
     SCALE) 
     .setScale(0, BigDecimal.ROUND_FLOOR) 
     .multiply(BigDecimal.valueOf(2)); 

System.out.println(z); 

Выход:

+0

Большое вам спасибо! Потрясающие. –

 Смежные вопросы

  • Нет связанных вопросов^_^