Erste Schritte Einfache Rechnung mit Exponenten

vince94

Mitglied
Hallo zusammen,

sitze gerade an einer kleinen Übungsaufgabe:

Folgender Wert ist zu berechnen: a*g + b*h + c*i + d*j + e*k + f*l

Folgende Werte wurden für die oben genannten Variablen gegeben:
a = 10^20; b = 1223; c = 10^18; d = 10^15; e = 3; f = - 10^12; g = 10^20; h = 2; i = - 10^22;
j = 10^13; k = 2111; l = 10^16.

Als Hinweis wurde das richtige Ergebnis gegeben: 8779.


Ich versuchte es mit folgendem Quelltext:

Java:
public class S83Aufgabe414a {
	public static void main (String[] args) {
		double a, b, c, d, e, f, g, h, i, j, k, l, m;
	// Deklaration der Variablen:
		a = Math.pow(10, 20);
		b = 1223;
		c = Math.pow(10, 18);
		d = Math.pow(10, 15);
		e = 3;
		f = - Math.pow(10, 12);
		g = Math.pow(10, 20);
		h = 2;
                i = - Math.pow(10, 22);
	        j = Math.pow(10, 13);
		k = 2111;
		l = Math.pow(10, 16);
	// Formel zur Berechnung der Variablen m:
	m = (a * g) + (b * h) + (c * i) + (d * j) + (e * k) + (f * l);
		System.out.println(m);

Mir wird "0.0" ausgegeben.
(Aber es sollte ja 8779 ausgegeben werden!)

Um den Fehler zu finden, habe ich jetzt Variable einzeln ausgegeben. Aber war alles korrekt.

Könnte mir einer von euch bitte helfen und mir einen Hinweis geben, wo der Fehler ist?

Vielen Dank

(Bitte seit gnädig mit mir; bitte ganz neuer Anfänger...😉)
 
Der Entscheidende Hinweis ist in den Bounds von double zu finden. Du verursachst mit ein paar Rechenoperationen Überläufe.
Es gibt 2 Möglichkeiten, wie du dem entgegenwirken kannst.

1. Stell die Formel so um das es nie zu Überläufen kommen kann

2. Verwende BigDecimal(kann riesige Fließkommazahlen darstellen - pendant ist BigInteger stellt ganzheitliche Zahlen dar)

Aber ich glaube du solltest die erste Variante verwenden. Hier die zweite Methode:

Java:
import java.math.BigDecimal;

public class S83Aufgabe414a {
	public static void main(String[] args) {
		BigDecimal a, b, c, d, e, f, g, h, i, j, k, l, m;
		// Deklaration der Variablen:
		
		a = BigDecimal.valueOf(Math.pow(10, 20));
		b = BigDecimal.valueOf(1223);
		c = BigDecimal.valueOf(Math.pow(10, 18));
		d = BigDecimal.valueOf(Math.pow(10, 15));
		e = BigDecimal.valueOf(3);
		f = BigDecimal.valueOf(-Math.pow(10, 12));
		g = BigDecimal.valueOf(Math.pow(10, 20));
		h = BigDecimal.valueOf(2);
		i = BigDecimal.valueOf(-Math.pow(10, 22));
		j = BigDecimal.valueOf(Math.pow(10, 13));
		k = BigDecimal.valueOf(2111);
		l = BigDecimal.valueOf(Math.pow(10, 16));
		// Formel zur Berechnung der Variablen m:
//		m = (a * g) + (b * h) + (c * i) + (d * j) + (e * k) + (f * l);
		m = a.multiply(g).add(b.multiply(h)).add(c.multiply(i)).add(d.multiply(j)).add(e.multiply(k)).add(f.multiply(l));
		System.out.println(m);
	}
}
 
Stell die Formel wie folgt um:
Java:
m = ((a * g) + (c * i) + (d * j) + (f * l)) + ((b * h) + (e * k));

Es ist gut dass du in diesen Fehler gelaufen bist, in deiner Aufgabe geht es um das Thema Rundungsfehler. Wenn eine Zahl von 2xxx mit einer so hohen Zahl wie 1^40 addiert und dieses Ergebnis mit einer anderen Zahl, die ebenfalls einen hohen negativen Wert hat, multipliziert wird, so "verpufft" deine Zahl als Rundungsfehler bei der Multiplikation. Es gibt viel Material darüber, kannst du in der gängigen IT-Literatur finden, z.B. Galileo Open Book usw. Oder hier ein sehr wissenschaftlicher Artikel:
What Every Computer Scientist Should Know About Floating-Point Arithmetic

Viel Spaß noch beim Lernen! 🙂
 

Zurück
Oben