Wurzel / negativer Exponent

Status
Nicht offen für weitere Antworten.

itzigk

Mitglied
Hallo,

ich habe ein programmiertechnisches Problem. Ich muss folgende Formel in Java berechnen:

unbenanntcva.jpg


Wobei:
n im Bereich von 40.000 bis 1.7 Millionen liegt
und P(x) meist im Bereich von 0,00001 - 0,5 liegt

Um überhaupt werte berechnen zu können nutze ich BigDecimal. Leider können für diesen Typ nur Int als Exponent genutzt werden. Ich habe eine Implementierung für das Wurzel Problem gefunden, jedoch endet dies immer mit einem Overflow aufgrund der Zahlen.

Java:
Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: Overflow

Ich wäre für Ideen oder Lösungsvorschläge dankbar.

mfg
 

itzigk

Mitglied
Hallo,

ich poste mal nur einen Auszug mit der Methode, die Fehlerzeile 236 entpricht im Auszug der Zeile 34.

Java:
 private static final int iBIAS_FOR_PRESION = 3;

	  private static final int iFINAL_COUNT = 101;

	  /** enthält die Werte der ersten 100 BigDecimals * */
	  public static final BigDecimal[] N = new BigDecimal[iFINAL_COUNT];

	  static {
	    for (int i = 0; i < iFINAL_COUNT; i++) {
	      N[i] = new BigDecimal(i);
	    }
	  }
/**
	   * Berechnet die k-te Wurzel des Radikanten.
	   * 
	   * @param bigdecimalRadikant Der Radikant.
	   * @param iRootExponent Der Exponent der Wurzel.
	   * @param mathcontextRounding Die Genauigkeit der Berechnung der Wurzel.
	   * @return Die berechnete Wurzel.
	   */
	  public static BigDecimal root(BigDecimal bigdecimalRadikant, int iRootExponent, MathContext mathcontextRounding) {
	    MathContext mathcontextRouningBiased = new MathContext(mathcontextRounding.getPrecision() + iBIAS_FOR_PRESION,
	      RoundingMode.HALF_EVEN);

	    BigDecimal bigdecimalXn = bigdecimalRadikant;
	    BigDecimal bigdecimalXnp1 = bigdecimalRadikant.divide(N[2], mathcontextRouningBiased);

	    while (bigdecimalXnp1.compareTo(bigdecimalXn) != 0) {
	      bigdecimalXn = bigdecimalXnp1;

	      bigdecimalXnp1 = N[1].divide(BigDecimal.valueOf(iRootExponent), mathcontextRouningBiased).multiply(
	        new BigDecimal(iRootExponent).subtract(N[1], mathcontextRouningBiased).multiply(bigdecimalXn,
	          mathcontextRouningBiased).add(
	          bigdecimalRadikant.divide(bigdecimalXn.pow(iRootExponent - 1, mathcontextRouningBiased),
	            mathcontextRouningBiased), mathcontextRouningBiased), mathcontextRouningBiased);
	    }

	    return bigdecimalXn.round(mathcontextRounding);
}

Java:
Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: Overflow
	at java.math.BigDecimal.checkScale(Unknown Source)
	at java.math.BigDecimal.multiply(Unknown Source)
	at java.math.BigDecimal.multiply(Unknown Source)
	at java.math.BigDecimal.pow(Unknown Source)
	at CountChars.root(CountChars.java:236)
	at CountChars.countChars(CountChars.java:170)
	at Gui$3.actionPerformed(Gui.java:285)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

Die Wurzel Funktion habe ich im Internet gefunden. Sie Funktioniert auch, jedoch nicht für meinen Zahlenbereich. Daher wollte ich meine Berechnug ändern auf eine Nutzung der Potenz.

Hier mal die Quelle zur Methode: https://svn.mayastudios.de/sopra/repos/sources/fred/branches/module-test1/src/de/ahija/MyFunx/BigDec2.java

mfg
 

Landei

Top Contributor
Bist du dir ganz sicher, dass es mit double nicht geht? Kann ich mir ehrlich nicht vorstellen.
 

itzigk

Mitglied
Hi,

ja leider nicht, bei double bin ich nach dem Multiplizieren von ca. 1000 Wahrscheinlichkeiten bei 0. Weil der bereich überschritten ist und es sollen bis zu 1,5 Millionen wahrscheinlichkeiten multipliziert werden.
Als ungefähre größe bei 1000 Werten verschiebt sich die Zahl ungefähr 1000 mal sodas die zahl mindestens unter 1*10^-1000 liegt.

mfg
 

Landei

Top Contributor
Es gibt aber Tricks, wie man sowas umgehen kann. Was du z.B. versuchen könntest, wäre bei einem langen Produkt

p = a1*a2*a3*...*an //alle a sind positiv

erst einmal

t = ln(a1)+ln(a2)+ln(a3)+...+ln(an)

zu berechnen und dann

p = e^t

Die Logarithmen "konzentrieren" die Zahlen auf einen kleineren Bereich, in dem genauer gerechnet werden kann, so dass sich die Ungenauigkeiten nicht so hochschaukeln (zumindest in der Theorie)
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben