2010-08-26 30 views
20

Küçük projemde Math.pow (7777.66, 5555.44) gibi bir şeyi sadece çok büyük sayılarla yapmam gerekiyor. Birkaç çözümleri rastladım:Java'da BigDecimal'de kesirli bir güç nasıl yapılır?

  • Kullanım çift - ama sayılar
  • Kullanım BigDecimal.pow çok büyük ama fraksiyonel
  • Kullanım için destek X^(A + B) = X^A * X^B formülü (B, ikinci num'in geri kalanıdır), ancak yine de büyük X veya büyük A için destek yok, çünkü hala çift
  • 'a dönüyorum. Bir çeşit Taylor serisinde algoritma veya benzeri bir şey kullanıyorum. Matematikte çok iyi değil, bu yüzden herhangi bir çözüm bulamamış olsam son seçeneğim (bazı kütüphaneler veya (A + B) için bir formül (C + D)).

Herkes kütüphane ya da kolay bir çözümü biliyor? Birçok insanın aynı sorunla uğraştığını düşünmüştüm ...

p.s. ApFloat adlı bir kütüphane buldum, ancak bunu yaklaşık olarak yaptım, ama elde ettiğim sonuçlar o kadar yakındı ki, 8^2 bile bana 60 ...

+0

, 8^2 = 64 sesler size (benim özel sabitleri vb görmezden) aşağıdakileri yapabilirsiniz Bu şekilde Zayıf ve 2^100^100 küçültülmelidir. – stacker

+0

Formül numarasını denediğimi söylemeliyim ve milyonlarca basamaklı sayılarla bile çok iyi çalışıyor! (Çift ve int hakkında her şeyi bilmiyorum gibi görünüyor) ... Örnekler: 50!^10! = 12.50911317862076252364259 * 10^233996181 50!^0.06 = 7395.788659356498101260513 Buraya posta göndermek biraz uzun ama X^(A + B) = X^A * X^B ... Nasıl ve neden (ve eğer) gerçekten çok büyük sayılarla çalıştığını anlamaya çalışıyorum. –

+0

Zaten çözümünü verdim http://stackoverflow.com/questions/11848887/bigdecimal-to-the-power-of-bigdecimal-on-java-android/22556217#22556217 –

cevap

21

de basamak MİLYONLARCA ile 1.7976931348623157E308 altında bağımsız değişkenler için çözüm (Double.MAX_VALUE) ancak destekleyici sonuçlar bir göz atın! çift ​​gibi görünüyor: 9.332621544394415E157), BigDecimal.doubleValue() kullanmak için sorun yoktur. Ama sadece Math.pow (double, double) yapmamalısınız çünkü sonuç MAX_VALUE'dan büyükse, sadece sonsuzluk elde edersiniz. SO: hesaplamayı X^(A + B) = X^A * X^B kullanarak hesaplamayı TWO güçlerine, büyük, BigDecimal.pow'u ve küçük olanı (2. argümanın kalanını kullanarak) Math kullanarak ayırın. pow, daha sonra çarpın. X, DOUBLE'a kopyalanacaktır - MAX_VALUE değerinden büyük olmadığından emin olun, A INT olacaktır (en fazla 2147483647, ancak BigDecimal.pow, tamsayıları bir milyardan fazla desteklememektedir) ve B, her zaman 1'den küçük olacak.

int signOf2 = n2.signum(); 
    try { 
     // Perform X^(A+B)=X^A*X^B (B = remainder) 
     double dn1 = n1.doubleValue(); 
     // Compare the same row of digits according to context 
     if (!CalculatorUtils.isEqual(n1, dn1)) 
      throw new Exception(); // Cannot convert n1 to double 
     n2 = n2.multiply(new BigDecimal(signOf2)); // n2 is now positive 
     BigDecimal remainderOf2 = n2.remainder(BigDecimal.ONE); 
     BigDecimal n2IntPart = n2.subtract(remainderOf2); 
     // Calculate big part of the power using context - 
     // bigger range and performance but lower accuracy 
     BigDecimal intPow = n1.pow(n2IntPart.intValueExact(), 
       CalculatorConstants.DEFAULT_CONTEXT); 
     BigDecimal doublePow = 
      new BigDecimal(Math.pow(dn1, remainderOf2.doubleValue())); 
     result = intPow.multiply(doublePow); 
    } catch (Exception e) { 
     if (e instanceof CalculatorException) 
      throw (CalculatorException) e; 
     throw new CalculatorException(
      CalculatorConstants.Errors.UNSUPPORTED_NUMBER_ + 
       "power!"); 
    } 
    // Fix negative power 
    if (signOf2 == -1) 
     result = BigDecimal.ONE.divide(result, CalculatorConstants.BIG_SCALE, 
       RoundingMode.HALF_UP); 

Sonuçlar örnekler:! Eğer başarmak için denemek dair bir örnek verebilir misiniz

50!^10! = 12.50911317862076252364259*10^233996181 

50!^0.06 = 7395.788659356498101260513 
+2

Bu "CalculatorUtils", "CalculatorConstants" veya "CalculatorException" sınıfları – Supuhstar

+0

olmadan kullanışlı değildir. Örnek yararlı değilse, kullanmayın, bu bir örnektir. Bu yüzden "özel sabitlerimi görmezden geldim" yazdım. Zaten her birini tahmin edebilir veya değiştirebilirsiniz. –

0

Exponents = logaritma. örneğin MAX_VALUE (100 kadar çift destekler sayılar yana

:

Logarithm of a BigDecimal

+2

Eh? Eğer söylediğiniz şey kesinlikle eşanlamlı değiller ... –

+0

Bu sorunun kabul edilen yanıtına atıfta bulunulan kaynak kod sadece doğal kayıttan daha fazla çözüm içeriyor. – prunge

+1

@Prunge - Teşekkürler. Asla doğal kütük hakkında hiçbir şey söylemedim.Gerçekten, Gene Marin'in kabul ettiği cevaba bakarsanız, tarif ettiği şey logaritmiktir. X^(A + B) = X^A * X^B, log (baz X) A + log (base X) B = log (base X) (A * B) deyimine eşdeğerdir. Bu, sayıları yönetilebilir bir büyüklük sırasına getirmenize izin vermelidir. –