/**********************************************
 * Beispiel: 1002 - Tantrap
 * Aufgabe: Zeichen mit Suchbegriff vergleiche
 * Autor: Martin Pickelbauer
 * Matrikel-Nummer: 0326586
 * Mail: e0326586@student.tuwien.ac.at
 * Project started: 23.11.2003
 * Last edited: 26.11.2003 02:40
 * Dokumentation: siehe Tantrap.txt
**********************************************/

import eprog.*;

public class Tantrap extends EprogIO {

    //************************
    //  KONSTANTEN FESTLEGEN *
    // ***********************
    
    public static int ENDZEICHEN = 100;              // Zeichen, wo das Einlesen des Ausdruckes abgebrochen wird
    public static int MIN_EXPONENTEN = 0;            // Minimaler Exponent
    public static int MAX_EXPONENTEN = 8;            // Maximaler Exponent
    public static double TEILINTERVALLBREITE = 0.2;  // Grosse des Teilintervalles !!! <- WARUM da double und net float?

    public static void main(String[] args) {
	
	//****************************
	//  VARIABLEN INITIALISIEREN *
	// ***************************
	
	float uGrenze = 0;                    // untere Integralgrenze
	float oGrenze = 0;                    // obere Integralgrenze
	float ergebnis;                       // Gesamtergebnis der Berechnung
	int koeffizientenEinlesung = 0;       // Variable für Koeffizienten-Einlesung, Initialisierung mit 0
	int exponent = 0;                     // Variable für Exponenten-Einlesung, Initialisierung mit 0 
	boolean gleicheGrenzen = false;       // Integralgrenzen chekcen, wenn Grenzen gleich dann true
	boolean eingabeEnde = false;          // zeigt an, ob Eingabe beendet werden soll (da Endzeichen erreicht)
	boolean falscheEingabe = false;       // falscheEingabe = true wenn Fehler im Eingabedatensatz
	boolean sofortEnde = false;           // wenn True, bricht sofort schleife ab
	
	int[] koeffizientToExponent = new int[MAX_EXPONENTEN+1];
	    for (int i=0; i<=MAX_EXPONENTEN; i++) {
		koeffizientToExponent[i] = 0; 
	     }
	
	//**************************
	// EINLESEN DES AUSDRUCKES *
	//**************************
	
	try {
	    float grenze1 = readFloat();
	    float grenze2 = readFloat();
	
	    if (grenze1 != grenze2) {                          // Uberprufung der Grenzen, wenn Grenzen gleich => Ergebnis=0
		oGrenze = Math.max(grenze1,grenze2);
		uGrenze = Math.min(grenze1,grenze2);
	    } else {
		gleicheGrenzen = true;
       	    }
	   
            koeffizientenEinlesung = readInt();	               // Koeffizienten einlesen
	    if (koeffizientenEinlesung == ENDZEICHEN) {
	        sofortEnde = true;
	    }
	    else {
	        while (eingabeEnde == false) {                 // so lange Schleife machen, bis ich nicht mehr einlesen soll (eingabeEnde eben true)
	            exponent = readInt();
	            
	            if (exponent == ENDZEICHEN) {
	                eingabeEnde = true;
	                falscheEingabe = true;
	            }
	            else {
	                // wenne MIN_EXPONENTEN <= Exponent <= MAX_EXPONENTEN und noch nichts im Array steht an der Stelle Exponent
	                if (exponent >= MIN_EXPONENTEN && exponent <= MAX_EXPONENTEN && koeffizientToExponent[exponent] == 0) {
    		            koeffizientToExponent[exponent] = koeffizientenEinlesung;
    		        }
    		        else {
  		            falscheEingabe = true;
    		        }
    	            }
    	            
    	            // wenn Exponent nicht Endzeichen (im Falle das Exponent = Endzeichen ist,
    	            // dann hätte er Koeffizienten wieder einlesen wollen und wäre in Endlosschleife hängen geblieben
	            if (exponent != ENDZEICHEN) {                       
	                koeffizientenEinlesung = readInt();
	               
	                if (koeffizientenEinlesung == ENDZEICHEN) {
	                    eingabeEnde = true;                        
	                }
	            }
	        }
	    }
	    
	    if (falscheEingabe == true || sofortEnde == true) {
	        EprogIO.println("FALSCHE EINGABE");
	    }
	    else {	    
	        if (gleicheGrenzen == true) {
	            EprogIO.println("0");
	        }
	        else {
    	            /****************************
    	            * BERECHNUNG DES AUSDRUCKES *
    	            ****************************/
    	    
    	            long n;                            // Anzahl der Teilintervalle <-- WARUM da float? müsste ja int sein
    	            float grenzenDifferenz;           // die Differenz zwischen uGrenze und oGrenze
    	            float xk;                         // Zwischenwert x k
    	            float xk_minus_1;                 // Zwischenwert x k-1
    	            float xk_zwischenWert;            // Zwischenwert x k-1 plus x k durch 2
    	            float teilSumme;                  // Teilsumme
    	            float gesamtSumme = 0;            // Gesamtsumme der Teilsummen
    	    
    	            grenzenDifferenz = oGrenze - uGrenze;                     // Differenz zwischen den Integralgrenzen
    	            
    	            // Wenn der Unterschied der 2 Grenzen kleiner als die Teilintervallbreite wäre, würde er als Rundungsergebnis 0 bekommen
    	            // und würde dann in weiterer Folge durch 0 dividieren, was wiederum auch ein Fehler ist. Darum weise ich n=1 zu,
    	            // um mind. 1 Teilintervall zu haben, was mathematisch kein Fehler ist, jedoch die Genauigkeit nicht so genau wird.
    	            
    	            if (grenzenDifferenz < TEILINTERVALLBREITE) {
    	                n = 1;
    	            }
    	            else {
    	                n = Math.round(grenzenDifferenz/TEILINTERVALLBREITE);    
    	            }
    	            
    	            for (int k=1; k<=n; k++) {
    		        xk_minus_1 = uGrenze + (((oGrenze-uGrenze)/n)*(k-1));
    		        xk = uGrenze + (((oGrenze-uGrenze)/n)*k);
    		        xk_zwischenWert = (xk_minus_1 + xk)/2;
    		        
       		        teilSumme = 0;
    		        for (int exp = MIN_EXPONENTEN; exp <= MAX_EXPONENTEN; exp++) {
    		            double blub = exp + Math.pow(xk_zwischenWert,exp);
    		            teilSumme += koeffizientToExponent[exp] * (Math.pow(xk_zwischenWert,exp));
    		        }
    		        gesamtSumme += teilSumme;
    	            }
    	    
    	            ergebnis = (oGrenze-uGrenze)/n * gesamtSumme;  // Ergebnis berechnen
    	            printFixedln(ergebnis);	                   // Ausgabe des Ergebnisses mit 3 Kommastellen
	        }
	    }
	}
	catch (EprogException e) {                                 // FEHLERMELDUNG rausschmeissen, wenn Eingabedaten nicht stimmen
	    EprogIO.println("?");
	}
     }
}