// Lösen quadratischer, kubischer und biquadratischer Gleichungen
// Javascript von Arndt Brünner, 5.7.2001, Version: 22.5.2004  



//var x21r=0.0,x21i=0.0,x22r=0.0,x22i=0.0;
//var x31r=0.0,x31i=0.0,x32r=0.0,x32i=0.0,x33r=0.0,x33i=0.0;
var x1r=0.0,x1i=0.0,x2r=0.0,x2i=0.0,x3r=0.0,x3i=0.0,x4r=0.0,x4i=0.0;
var fxr=0.0,fxi=0.0,nwr=0.0,nwi=0.0;
var Erl=false,GLL="",txt="";
var ustr="—————————————————————————————————————————————————————————————————————————————————————————";
var quadrErg=false;
var nNw=20;
var keineMeldung=1==0;

function solvePolynom(g)
{
	Erl=(g<0);g=g*sgn(g);if(Erl)document.f.text.focus();txt="";
	var a,b,c,d,e;
	nNw=Number(document.f.nNewton.value);if(isNaN(nNw))nNw=0;
	document.f.nNewton.value=nNw;
	if (g==2)
	{
		document.f.x21.value="";		
		document.f.x22.value="";		
		a=Number(String(document.f.p2a.value).replace(/\,/,"."));
		b=Number(String(document.f.p2b.value).replace(/\,/,"."));
		c=Number(String(document.f.p2c.value).replace(/\,/,"."));
		Quad(a,b,c);
		document.f.x21.value=Newton(x1r,x1i,0,0,a,b,c,nNw);		
		if((x1r!=x2r)||(x1i!=x2i))document.f.x22.value=Newton(x2r,x2i,0,0,a,b,c,nNw);
		test(0,0,a,b,c,2);
		document.f.text.value=txt.replace(/\. /g,"@@").replace(/\./g,",").replace(/@@/g,". ").replace(/-,/g,"-0,").replace(/ ,/g," 0,");	
		if(a==0)
		{
			document.f.p2a.value=0;
			if(b==0)
			{
				document.f.x21.value="¤    L = "+((c==0)?"R":"{ }");
				document.f.p2b.value=0;
			}
			else
			{
				document.f.x21.value=String(x1r).replace(/\./,",");
				if(c==0)document.f.p2c.value=0;
			}
		}
	}
	if (g==3)
	{
		document.f.x31.value="";		
		document.f.x32.value="";		
		document.f.x33.value="";		
		a=Number(String(document.f.p3a.value).replace(/\,/,"."));
		b=Number(String(document.f.p3b.value).replace(/\,/,"."));
		c=Number(String(document.f.p3c.value).replace(/\,/,"."));
		d=Number(String(document.f.p3d.value).replace(/\,/,"."));
		if (a==0)
		{
			Quad(b,c,d);
			document.f.x31.value=Newton(x1r,x1i,0,0,b,c,d,nNw);		
			document.f.x32.value=Newton(x2r,x2i,0,0,b,c,d,nNw);
			test(0,0,b,c,d,2);	
			document.f.text.value=txt.replace(/\. /g,"@@").replace(/\./g,",").replace(/@@/g,". ").replace(/-,/g,"-0,").replace(/ ,/g," 0,");	
			return;	
		}
		Kub(a,b,c,d);
		document.f.x31.value=Newton(x1r,x1i,0,a,b,c,d,nNw);		
		document.f.x32.value=Newton(x2r,x2i,0,a,b,c,d,nNw);		
		document.f.x33.value=Newton(x3r,x3i,0,a,b,c,d,nNw);		
		document.f.text.value=txt.replace(/-\./g,"-0,").replace(/ \./g," 0,").replace(/\. /g,"@@").replace(/\./g,",").replace(/@@/g,". ");	
		test(0,a,b,c,d,3);	
	}
	if (g==4)
	{
		document.f.x41.value="";		
		document.f.x42.value="";		
		document.f.x43.value="";		
		document.f.x44.value="";		
		a=Number(String(document.f.p4a.value).replace(/\,/,"."));
		b=Number(String(document.f.p4b.value).replace(/\,/,"."));
		c=Number(String(document.f.p4c.value).replace(/\,/,"."));
		d=Number(String(document.f.p4d.value).replace(/\,/,"."));
		e=Number(String(document.f.p4e.value).replace(/\,/,"."));
		if ((a==0)&&(b==0))
		{
			Quad(c,d,e);
			Newton(x1r,x1i,0,0,c,d,e,10);
			document.f.x41.value=L(nwr,nwi);		
			Newton(x2r,x2i,0,0,c,d,e,10);
			document.f.x42.value=L(nwr,nwi);
			test(0,0,c,d,e,2);	
			document.f.text.value=txt.replace(/\. /g,"@@").replace(/\./g,",").replace(/@@/g,". ").replace(/-,/g,"-0,").replace(/ ,/g," 0,");	
			return;	
		}
		if (a==0)
		{
			Kub(b,c,d,e);
			Newton(x1r,x1i,0,b,c,d,e,nNw);
			document.f.x41.value=L(nwr,nwi);		
			Newton(x2r,x2i,0,b,c,d,e,nNw);
			document.f.x42.value=L(nwr,nwi);		
			Newton(x3r,x3i,0,b,c,d,e,nNw);
			document.f.x43.value=L(nwr,nwi);		
			test(0,b,c,d,e,3);	
			document.f.text.value=txt.replace(/\. /g,"@@").replace(/\./g,",").replace(/@@/g,". ").replace(/-,/g,"-0,").replace(/ ,/g," 0,");	
			return;
		}
		QQuad(a,b,c,d,e);
		Newton(x1r,x1i,a,b,c,d,e,nNw);x1r=nwr;x1i=nwi;
		document.f.x41.value=L(nwr,nwi);		
		Newton(x2r,x2i,a,b,c,d,e,nNw);x2r=nwr;x2i=nwi;
		document.f.x42.value=L(nwr,nwi);		
		Newton(x3r,x3i,a,b,c,d,e,nNw);x3r=nwr;x3i=nwi;
		document.f.x43.value=L(nwr,nwi);		
		Newton(x4r,x4i,a,b,c,d,e,nNw);x4r=nwr;x4i=nwi;
		document.f.x44.value=L(nwr,nwi);
		document.f.text.value=txt.replace(/\. /g,"@@").replace(/\./g,",").replace(/@@/g,". ").replace(/-,/g,"-0,").replace(/ ,/g," 0,");	
	 	test(a,b,c,d,e,4);	
	}
}

function Newton(xr,xi,a,b,c,d,e,n)
{
	var bb=a*4,cc=b*3,dd=c*2,ee=d,d0=DNull(xr,xi,a,b,c,d,e),d1,xrt=xr,xit=xi;
	nwr=xr;nwi=xi;
	if(d0==0)return L(xr,xi);
	//if(xr==""){nwr="";nwi="";return "";}
	for(i=0;i<n;i++)
	{
		F(xr,xi,a,b,c,d,e);yr=fxr;yi=fxi;
		F(xr,xi,0,bb,cc,dd,ee);yyr=fxr;yyi=fxi;
		//alert("F("+L(xr,xi)+") = "+L(yr,yi)+"\nF\'("+L(xr,xi)+") = "+L(yyr,yyi));
		var N=(yyr*yyr+yyi*yyi);if(N==0){break;}
		xrt-=(yr*yyr+yi*yyi)/N;
		xit+=(yr*yyi-yi*yyr)/N;
		if(Math.abs((yr*yyr-yi*yyi)/N)>0.5)break;
		d1=DNull(xr,xi,a,b,c,d,e);
		//alert(L(xr,xi)+"\n"+L(xrt,xit)+"\n"+d0+"\n"+d1);
		if(d1>d0)break;
		d0=d1;
		xr=xrt;xi=xit;
	}
	nwr=Runden_(xr);nwi=Runden_(xi);
	return(L(nwr,nwi));
}
	

function F(xr,xi,a,b,c,d,e)
{
	var xr2=xr*xr,xr3=xr2*xr,xr4=xr2*xr2,xi2=xi*xi,xi3=xi2*xi,xi4=xi2*xi2;
	fxr=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
	fxi=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
}

function DNull(xr,xi,a,b,c,d,e)
{
	F(xr,xi,a,b,c,d,e)
	return Math.sqrt(fxr*fxr+fxi*fxi);
}

function L(r,i)
{
	var t=new String(r);
	if (i>0)
		t+=" + "+i+"·î";
	else if (i<0)
		t+=" - "+Math.abs(i)+"·î"
	if(t.charAt(0)==".")t=0+t;
	t=(" "+t).replace(/\./g,",").replace(/-,/g,"-0,").replace(/ ,/g," 0,").replace(/ 1·î/," î").replace(/ 0 \+ /," ").replace(/ 0 - /," -");
	return t.substring(1,t.length);
}

function GL(v,a,b,c,d,e)
{
	var t="",aa=((a==1)||(a==-1))?((a==1)?"":"-"):String(a),
	bb=((b==1)||(b==-1))?((b==1)?"":"-"):String(b),
	cc=((c==1)||(c==-1))?((c==1)?"":"-"):String(c),
	dd=((d==1)||(d==-1))?((d==1)?"":"-"):String(d),
	ee=String(e);
	//alert(v+" "+a+" "+b+" "+c+" "+d+" "+e);
	if(a!=0)t=aa+v+"^4"; if(b!=0)t+="+"+bb+v+"³";
	if(c!=0)t+="+"+cc+v+"²"; if(d!=0)t+="+"+dd+v; if(e!=0)t+="+"+ee;
	t=" "+t.replace(/\+\-/g,"-").replace(/\+/g," + ").replace(/\./g,",").replace(/\-/g," - ").replace(/ ,/g," 0,").replace(/\+/g," + ").replace(/\s\s/g," ");
	//alert("|"+t+"  "+t.indexOf("+"));
	if(t.substr(0,4)=="  - ")t=" -"+t.substring(4,t.length);
	if(t.substr(0,3)=="  +")t=" "+t.substring(3,t.length);
	if(t==" ")t=" 0";
	return " "+t+" ";
}

function Quad(a,b,c)
{//alert("Quad\n"+a+"\n"+b+"\n"+c);
	GLL=GL("x",0,0,a,b,c)+"= 0 ";
	if(Erl)txt+="Lösen der Gleichung "+GLL+"\n"+ustr.substr(0,GLL.length+21)+"\n\n";
	if(a==0)
	{
		if(b==0)
		{
			if(Erl)txt+="Die Gleichung "+GLL+" enthält keine Variable. \nSie hat die Lösungsmenge "+((c==0)?"R, da  0 = 0  immer gilt. ":"{ } (leere Menge), da  "+c+" = 0  niemals gilt. ");
			x1r="";x2r="";x1i=0;x2i=0;return;
		}
		x1r=-c/b;x1i=0;
		x2r=x1r;x2i=0;
		if(Erl)
		{
			txt+="Die Gleichung "+GLL+" ist keine quadratische, sondern eine lineare Gleichung,\ndenn in ihr kommt kein x² vor. \n";
			txt+="\nIhre Lösung gewinnt man so:\n\n\n";
			if(c!=0)txt+=GLL+"  \t| "+((c>0)?("-"+c):("+"+(-c)))+"\n\n";
			txt+="   "+GL("x",0,0,0,b,0)+" = "+(-c);
			if(b!=1)
			{
				txt+="  \t| "+((b==-1)?"·":":")+((b<0)?("("+b+")"):b)+"\n\n";
				txt+="      x = "+(-c/b)+"\n\n";
			}
		}
		return 1;		
	}
	var p=b/a,q=c/a;
	var r=p*p/4-q;
	if (r>0)
	{
		x1r=CheckDez(0,a,b,c,-p/2-Math.sqrt(r),1000000000);x1i=0;
		x2r=CheckDez(0,a,b,c,-p/2+Math.sqrt(r),1000000000);x2i=0;
	}
	else if(r==0)
	{
		x1r=-p/2;x1i=0;
		x2r=x1r;x2i=x1i;
	}
	else
	{
		x1r=-p/2;x1i=-Math.sqrt(-r);
		x2r=-p/2;x2i=Math.sqrt(-r);
	}

	Newton(x1r,x1i,0,0,a,b,c,nNw);x1r=nwr;x1i=nwi;
	Newton(x2r,x2i,0,0,a,b,c,nNw);x2r=nwr;x2i=nwi;


    x1r=Runden_(x1r);
    x1i=Runden_(x1i);
    x2r=Runden_(x2r);
    x2i=Runden_(x2i);

    CheckKomplex(0,0,a,b,c,x1r,x1i,0.000001);
    CheckKomplex(0,0,a,b,c,x2r,x2i,0.000001);

	if((Erl)&&(b!=0))
	{
		if(a!=1)txt+="Zunächst wird die Gleichung durch Division mit dem Koeffizienten vor x²\nauf Normalform gebracht:\n\n";else txt+="Die Gleichung liegt bereits in Normalform vor:\n\n";
		txt+=GL("x",0,0,1,b/a,c/a)+" = 0\n\n";
		txt+="An der Normalform werden p und q abgelesen.\np ist der Faktor vor dem x, und q ist die einzelne Zahl:\n\n";
		txt+="  p = "+p+"    q = "+q;
		txt+="\n\nDiese Werte werden in die p-q-Lösungsformel für x  und x  eingesetzt:\n";
		txt+="                                                 1      2\n\n";
		txt+="                ___________                        ___________ \n";
		txt+="          p     |  p²      |                p     |  p²       |\n";
		txt+="  x  = - ——— -  | ——— - q           x  = - ——— +  | ——— - q\n";   
		txt+="   1      2    \\|  4                 2      2    \\|  4\n\n";
		pp=(p<0)?"("+p+")":String(p);
		txt+="  x  = -"+pp+"/2 - sqr( "+pp+"²/4 "+((q<0)?"+ ":"- ")+Math.abs(q)+" )\n";
		txt+="   1  \n     = "+ (-p/2)+" - sqr( "+p*p/4+((q<0)?" + ":" - ")+Math.abs(q)+" )\n\n";
		if(x1i!=0)
		{txt+="      Vorsicht: negativer Radikand, daher keine reelle Lösung!\n\n";
		txt+="     = "+-p/2+" - sqr("+(p*p/4-q)+")\n\n";
		txt+="     = "+L(x1r,x1i)+"\n\n\n";
		}else
		{txt+="     = "+-p/2+" - sqr("+(p*p/4-q)+")\n\n";
		txt+="     = "+-p/2+" - "+Math.sqrt(p*p/4-q)+"\n\n     = "+x1r+"\n\n\n";}
		txt+="  x  = -"+pp+"/2 + sqr( "+pp+"²/4 "+((q<0)?"+ ":"- ")+Math.abs(q)+" )\n";
		txt+="   2  \n     = "+ (-p/2)+" + sqr( "+p*p/4+((q<0)?" + ":" - ")+Math.abs(q)+" )\n\n";
		if(x1i!=0)
		{txt+="      Vorsicht: negativer Radikand, daher keine reelle Lösung!\n\n";
		txt+="     = "+-p/2+" + sqr("+(p*p/4-q)+")\n\n";
		txt+="     = "+L(x2r,x2i)+"\n\n\n";
		}else
		{txt+="     = "+-p/2+" + sqr("+(p*p/4-q)+")\n\n";
		txt+="     = "+-p/2+" + "+Math.sqrt(p*p/4-q)+"\n\n     = "+x2r+"\n\n";}
		if((Math.abs(p)==1)&&(q==-1))txt+="\n"+ustr+"\n         Diese Gleichung führt auf das Zahlenverhältnis des goldenen Schnitts!\n"+ustr+"\n";
	}
	if((Erl)&&(b==0))
	{
		if(a!=1)txt+="Zunächst wird die Gleichung durch Division mit dem Koeffizienten vor x² auf\nNormalform gebracht. \n\n";else txt+="Die Gleichung liegt bereits in Normalform vor:\n\n";
		txt+=GL("x",0,0,1,b/a,c/a)+"= 0\n\n";
		if(c!=0){txt+="Nun wird das absolute Glied auf die andere Seite gebracht. \n\n";
		txt+=GL("x",0,0,1,0,0)+"= "+(-c/a)+"\n\n";}
		txt+="Auf beiden Seiten wird die Wurzel gezogen. ";
		if(c/a>0)txt+="\n\nVorsicht: Da die rechte Seite negativ ist, sind die Resultate keine reellen Zahlen,\nsondern Vielfache der imaginären Einheit î. ";
		txt+="\n\n   x = sqr("+(-c/a)+")\n\n";
		txt+="   x = "+L(x1r,x1i)+"\n    1\n\n   x = "+L(x2r,x2i)+"\n    2\n";
	}
	return 2;
}

//Findet die Lösungen von Polynomen 3. Grades
function Kub(a,b,c,d)
{//alert("Kub\n"+a+"\n"+b+"\n"+c+"\n"+d);
	if(a==0)return Quad(b,c,d);
	GLL=GL("x",0,a,b,c,d)+"= 0 ";
	if(Erl)txt+="Lösen der kubischen Gleichung "+GLL+"\n"+ustr.substr(0,GLL.length+30)+"\n\n";
    pi = Math.PI;
    var n=-1;
    var r = b/a;
    var s = c / a;
    var t = d / a;
    var p = s - r * r / 3.0; 
    var q = 2*r*r*r/27.0 - r*s/3.0 + t;
    var radikand = q * q / 4.0 + p * p * p / 27.0; 
	if(Erl)
	{
		if(a!=1)txt+="Die kubische Gleichung wird zunächst durch Division mit "+a+" auf die Normalform \nx³ + rx² + sx + t = 0 gebracht. \n\n"+GL("x",0,1,b/a,c/a,d/a)+" = 0\n\n";
		else txt+="Die kubische Gleichung liegt bereits in der Normalform x³ + rx² + sx + t = 0 vor. \n\n";
		if(b!=0) {txt+="Durch die Substitution x = y - r/3 wird die Gleichung in eine reduzierte Form \ny³ + py + q = 0 gebracht, in der kein quadratisches Glied mehr auftritt. \n\n";
		if(r>0)txt+=GL("(y-"+r/3+")",0,1,r,s,t)+"= 0\n\n";else txt+=GL("(y+"+(-r/3)+")",0,1,r,s,t)+"= 0\n\n";
		txt+="Die neuen Koeffizienten können bequemer auch direkt berechnet werden:\n\n";
		txt+="   p = s - r²/3 = "+p+"\n   q = 2r³/27 - rs/3 + t = "+q+"\n\n";
		txt+=GL("y",0,1,0,p,q)+" = 0\n\n";}
		else txt+="Die Gleichung liegt bereits in einer reduzierten Form y³ + py + q = 0 vor,\nin der die Unbekannte nicht im Quadrat erscheint. Dies ist nötig, um die \nLösungsformel von Cardano/Tartaglia anwenden zu können. \n\n";
		txt+="Aus der Gleichung"+((b==0)?GL("y",0,1,0,p,q)+"= 0  ":" ")+"liest man also ab:\n\n   p = "+p+"            q = "+q+"\n\n";
		txt+="Nun muß der Wert R = (q/2)²+(p/3)³ betrachtet werden. \n\nIst R > 0, so hat die kubische Gleichung eine reelle und zwei komplexe Lösungen, ";
		txt+="\nist R = 0, hat sie drei reelle Lösungen, von denen zwei zusammenfallen, \nund im Falle R < 0 drei verschiedene reelle Lösungen. \n\nFür die ersten beiden Fälle ";
		txt+="verwendet man die Lösungsformel von Cardano/Tartaglia,\nim dritten Fall, dem sogenannten \"casus irreducibilis\", löst man mithilfe\ntrigonometrischer Funktionen. \n\n";
		txt+="Im Falle dieser Gleichung ist R = "+String(radikand)+". \n\n";
	}
	if (radikand >=0)
	{
            var wurz = Math.sqrt(radikand);
            var u = Math.pow( Math.abs( -q / 2 + wurz), 1/3)*sgn(-q/2+wurz);
            var v = Math.pow(Math.abs(-q / 2 - wurz) , 1/3)*sgn(-q/2-wurz);
            x1r= u + v; x1i= 0;
            var im = (u - v) / 2 * Math.sqrt(3.0);
            x2r=-(u + v) / 2 ; x2i=-im;
            x3r= -(u + v) / 2 ; x3i= im;
		if (im !=0) n=1; else n=3;

		if(Erl)
		{
			txt+="Da R nicht negativ ist, kann die Gleichung mit der Cardanischen Formel gelöst werden:\n\n";
			txt+="\n   T = sqr((q/2)²+(p/3)³) = sqr(R) = "+ wurz +"\n\n   u = kubikwurzel(-q/2 + T) = "+u+"\n\n   v = kubikwurzel(-q/2 - T) = "+v+"\n\n";
			txt+="   y  = u + v = "+Runden_(x1r)+"\n    1\n   y  = -(u + v)/2 - ((u - v)/2)*sqr(3)·î = "+L(x2r,x2i)+"\n    2\n   y  = -(u + v)/2 + ((u - v)/2)*sqr(3)·î = "+L(x3r,x3i)+"\n    3\n\n";

		}
	}
    else
	{

        var rr = Math.sqrt(-p * p * p / 27.0); 
        var cosphi = (-q / 2.0) / rr;
        var phi=Math.acos(cosphi);
        var dingens = 2.0 * Math.pow(rr , 1.0/3.0);
        x1r=dingens * Math.cos(phi/3.0); x1i= 0;
        x2r=dingens * Math.cos(phi/3.0 + 2.0 * pi / 3.0); x2i= 0;
        x3r=dingens * Math.cos(phi/3.0 + pi * 4.0 / 3.0); x3i= 0; 
		n=3;
	if(Erl)
	{
		txt+="Da R < 0, liegt der casus irreducibilis vor. Man erhält die Lösungen mit\ny = 2·kubikwurzel(u)·cos(w/3 + v), wobei u = sqr(-(p/3)³) und cos(w) = -q/(2u) ist, ";
		txt+="\nund v die Werte 0, 120° und 240° annimmt. \n\n";
		txt+="   cos(w) = "+cosphi+"   u = "+rr+"\n\n";
		txt+="   y  = "+Runden_(x1r)+"\n    1\n   y  = "+Runden_(x2r)+"\n    2\n   y  = "+Runden_(x3r)+"\n    3\n\n";

	}


    }
    x1r -= r / 3.0;
    x2r -= r / 3.0;
    x3r -= r / 3.0;

	var xx;

    if(x1i==0)x1r=CheckDez(a,b,c,d,x1r,10000000000);
    if(x2i==0)x2r=CheckDez(a,b,c,d,x2r,10000000000);
    if(x3i==0)x3r=CheckDez(a,b,c,d,x3r,10000000000);
    if(n==3)
    {
	while((x1r>x2r)||(x2r>x3r)){
		if(x2r<x1r){ xx=x1r;x1r=x2r;x2r=xx;}
		if(x3r<x2r){ xx=x2r;x2r=x3r;x3r=xx;}
	}
    }
	Newton(x1r,x1i,0,1,r,s,t,nNw);x1r=nwr;x1i=nwi;
	Newton(x2r,x2i,0,1,r,s,t,nNw);x2r=nwr;x2i=nwi;
	Newton(x3r,x3i,0,1,r,s,t,nNw);x3r=nwr;x3i=nwi;

    x1r=Runden_(x1r);
    x1i=Runden_(x1i);
    x2r=Runden_(x2r);
    x2i=Runden_(x2i);
    x3r=Runden_(x3r);
    x3i=Runden_(x3i);
	if(Erl)
	{
		if(r!=0)
		{
			txt+="Die Substitution x = y - r/3 wird durch Subtraktion von r/3 rückgängig gemacht. \nr="+L(r,0)+" ist der quadratische Koeffizient der kubischen Gleichung. \nDamit ergeben sich, der Größe nach geordnet, diese Lösungen:\n\n";
		}
		else
		{
			txt+="Der Größe nach geordnet ergeben sich also diese Lösungen der kubischen Gleichung:\n\n";
		}
		txt+="   x  = "+L(x1r,x1i)+"\n    1\n   x  = "+L(x2r,x2i)+"\n    2\n   x  = "+L(x3r,x3i)+"\n    3\n\n";
	}

	err=0;
    if((err=CheckKomplex(0.0,a,b,c,d,x1r,x1i,0.001))>0.1){if(!keineMeldung)alert("Lösung 1 falsch: "+err)};
    if((err=CheckKomplex(0.0,a,b,c,d,x2r,x2i,0.001))>0.1){if(!keineMeldung)alert("Lösung 2 falsch: "+err)};
    if((err=CheckKomplex(0.0,a,b,c,d,x3r,x3i,0.001))>0.1){if(!keineMeldung)alert("Lösung 3 falsch: "+err)};
    return n ;
}

var sqr2=Math.sqrt(2);

function QQuad2(A,B,C,D,E)
{
	var a=B/A, b=C/A, c=D/A, d=E/A, ERL=false;
	var p=b-3*a*a/8, 
          q=a*(a*a/8-b/2)+c, 
          r=-(3*a*a*a*a - 16*a*a*b + 64*a*c - 256*d)/256;
	var n=Kub( 1.0 , -p/2.0 , -r , (4.0*p*r-q*q)/8.0 );
	var z=(n==1)? x1r : x3r;
	var w1=Math.sqrt(2.0*z-p),w2=Math.sqrt(z*z-r);
	Quad(1.0,w1,z-w2);    	//	test(0,0,1,w1,z-w2,2);//alert("?");
	x3r=x1r;x3i=x1i;x4r=x2r;x4i=x2i;
	Quad(1.0,-w1,z+w2);   	//	test(0,0,1,-w1,z+w2,2);alert("?");
					//	test(1,0,p,q,r,4);alert('?');
	x1r=Runden_(x1r-a/4.0); x1i=Runden_(x1i);
	x2r=Runden_(x2r-a/4.0); x2i=Runden_(x2i);	
	x3r=Runden_(x3r-a/4.0); x3i=Runden_(x3i);	
	x4r=Runden_(x4r-a/4.0); x4i=Runden_(x4i);	
	
	test(1,a,b,c,d,4);
	
	return;
}

function QQuad(A,B,C,D,E)
{
	if(A==0)return Kub(B,C,D,E);
	var a=B/A, b=C/A, c=D/A, d=E/A, a4=a/4, ERL=false;
	var p=b-3*a*a/8, q=a*(a*a/8-b/2)+c, 
	r=-(3*a*a*a*a - 16*a*a*b + 64*a*c - 256*d)/256;
	var xq1r,xq1i,xq2r,xq2i;
	if((Erl)&&((B!=0)||(D!=0)))
	{
		GLL=GL("x",A,B,C,D,E)+"= 0 ";
		txt+="Lösen der biquadratischen Gleichung "+GLL+"\n"+ustr.substr(0,GLL.length+38)+"\n\n";
		if(A!=1)txt+="Die Gleichung wird zunächst durch Division mit "+A+" auf die Normalform \nx^4 + ax³ + bx² + cx + d = 0 gebracht. \n\n"+GL("x",1,a,b,c,d)+" = 0\n\n";
		else txt+="Die Gleichung liegt bereits in der Normalform x^4 + ax³ + bx² + cx + d = 0 vor. \n\n";
		if(B!=0)
		{
			txt+="Durch die Substitution x = y - a/4 wird die Gleichung in die Form \ny^4 + py² + qy + r = 0 gebracht, die kein kubisches Glied mehr aufweist. \n\n";
			if(a>0)txt+=GL("(y - "+a/4+")",1,a,b,c,d)+"= 0\n\n"; else txt+=GL("(y + "+(-a/4)+")",1,a,b,c,d)+"= 0\n\n";
			txt+="Statt auszumultiplizieren, kann man die neuen Koeffizienten auch direkt berechnen:\n\n   p = b - 3a²/8 = "+p+"\n   q = a³/8-ab/2+c = "+q+"\n";
			txt+="   r = -(3a^4 - 16a²b + 64ac - 256d)/256 = "+r+"\n\n";
			txt+=GL("y",1,0,p,q,r)+" = 0\n\n";
		}
		else txt+="Diese Gleichung hat die Form x^4 + px² + qy + r = 0, sie weist kein kubisches \nGlied mehr auf. \n\n";
		txt+="Diese Gleichung kann über ihre kubische Resolvente z³ - 2pz² + (p²-4r)z + q² = 0 \ngelöst werden. \n\n";
		txt+=GL("z",0,1,-2*p,p*p-4*r,q*q)+" = 0\n\nMan benötigt also zunächst die Lösungen dieser Gleichung. \n\n"+ustr+"\n\n\n";
		ERL=true;//Erl=false;
	}
	if((Erl)&&(B==0)&&(D==0))
	{
		GLL=GL("x",A,0,C,0,E)+"= 0 ";
		txt+="Lösen der biquadratischen Gleichung "+GLL+"\n"+ustr.substr(0,GLL.length+38)+"\n\n";
		txt+="In dieser Gleichung kommt die Unbekannte nur in der vierten "+((C==0)?"":"und in der zweiten ")+"Potenz vor. \n";
		txt+="Man wandelt sie durch die Substitution x² = y in eine quadratische Gleichung um:\n\n";
		txt+=GL("y",0,0,A,C,E)+"= 0        (*)\n\n";
		txt+="Diese wird gelöst:\n\n\n";
		Quad(A,C,E);
		xq1r=x1r;xq1i=x1i;xq2r=x2r;xq2i=x2i;
		Erl=false;ERL=true;
	}

	//alert(p+", "+q+", "+r );
	var n=Kub(1,-2*p,p*p-4*r,q*q);
	if((Erl)&&((B!=0)||(D!=0)))
	{
		Erl=true;
		txt+=ustr.substr(0,90)+"\n\nZurück zur Lösung der biquadratischen Gleichung. \n\nDas Lösungsverfahren für kubische Gleichungen ergab also für das z der \nkubischen Resolvente:\n\n";
		txt+="   z  = "+L(x1r,x1i)+"\n    1\n   z  = "+L(x2r,x2i)+"\n    2\n   z  = "+L(x3r,x3i)+"\n    3\n\n";
		txt+="Nach dem Satz von Vieta muß das Produkt der drei Lösungen gleich dem linearen Glied\nder Gleichung sein, hier also q² = "+(q*q)+". ";
		txt+="\nDie Lösungen für y ergeben sich nun folgendermaßen:\n\n";
		txt+="   y  = ( sqr(-z ) + sqr(-z ) + sqr(-z ) ) / 2\n    1           1          2          3\n";
		txt+="   y  = ( sqr(-z ) - sqr(-z ) - sqr(-z ) ) / 2\n    2           1          2          3\n";
		txt+="   y  = (-sqr(-z ) + sqr(-z ) - sqr(-z ) ) / 2\n    3           1          2          3\n";
		txt+="   y  = (-sqr(-z ) - sqr(-z ) + sqr(-z ) ) / 2\n    4           1          2          3\n\n";
		txt+="wobei jedoch die Wahl der Vorzeichen der Wurzeln so getroffen werden muß, daß deren\nProdukt gleich -q = "+(-q)+" ist. \n\n   Die Wurzeln\n\n";
	}
	W1r=new Array(0.0,0.0);W2r=new Array(0.0,0.0);W3r=new Array(0.0,0.0);W1i=new Array(0.0,0.0);W2i=new Array(0.0,0.0);W3i=new Array(0.0,0.0);
	sqrk(-x1r,-x1i,W1r,W1i); sqrk(-x2r,-x2i,W2r,W2i); sqrk(-x3r,-x3i,W3r,W3i);
	d0= Math.abs(W1r[0]*(W2r[0]*W3r[0] - W2i[0]*W3i[0]) - W1i[0]*(W2r[0]*W3i[0] + W2i[0]*W3r[0])+q);
	d1= Math.abs(W1r[0]*(W2r[0]*W3r[0] - W2i[0]*W3i[1]) - W1i[0]*(W2r[0]*W3i[1] + W2i[0]*W3r[1])+q);
	d2= Math.abs(W1r[0]*(W2r[1]*W3r[0] - W2i[1]*W3i[0]) - W1i[0]*(W2r[1]*W3i[0] + W2i[1]*W3r[0])+q);
	i=((d0<=d1)&&(d0<=d2))? 0:((d1<d2)?1:2);j=0; if(i==2){i=0;j=1;}
//	alert(d0+", "+d1+", "+d2+"  0 "+j+" "+i+"   "+(d0<d1)+",  "+(d0<d2));
	if((Erl)&&((B!=0)||(D!=0)))
	{
		txt+="   sqr("+L(-x1r,-x1i)+") = "+L(W1r[0],W1i[0])+"\n";
		txt+="   sqr("+L(-x2r,-x2i)+") = "+L(W2r[j],W2i[j])+"\n";
		txt+="   sqr("+L(-x3r,-x3i)+") = "+L(W3r[i],W3i[i])+"\n\n   erfüllen diese Bedingung. \n\n";
	}
	x1r = (W1r[0]+W2r[j]+W3r[i])/2-a4; x1i = (W1i[0]+W2i[j]+W3i[i])/2; 
	x2r = (W1r[0]-W2r[j]-W3r[i])/2-a4; x2i = (W1i[0]-W2i[j]-W3i[i])/2; 
	x3r = (-W1r[0]+W2r[j]-W3r[i])/2-a4; x3i = (-W1i[0]+W2i[j]-W3i[i])/2; 
	x4r = (-W1r[0]-W2r[j]+W3r[i])/2-a4; x4i = (-W1i[0]-W2i[j]+W3i[i])/2; 
	Newton(x1r,x1i,A,B,C,D,E,nNw);x1r=nwr;x1i=nwi;
	Newton(x2r,x2i,A,B,C,D,E,nNw);x2r=nwr;x2i=nwi;
	Newton(x3r,x3i,A,B,C,D,E,nNw);x3r=nwr;x3i=nwi;
	Newton(x4r,x4i,A,B,C,D,E,nNw);x4r=nwr;x4i=nwi;
	if((Erl)&&((B!=0)||(D!=0)))
	{
		txt+="Damit ergeben sich folgende Werte für y\n\n";
		txt+="   y  = "+L(x1r+a4,x1i)+"\n    1\n   y  = "+L(x2r+a4,x2i)+"\n    2\n   y  = "+L(x3r+a4,x3i)+"\n    3\n   y  = "+L(x4r+a4,x4i)+"\n    4\n\n";
		txt+="und nach Subtraktion von a/4 ( = "+a4+" ) die Lösungen der gegebenen \nbiquadratischen Gleichung:\n\n"
		txt+="   x  = "+L(x1r,x1i)+"\n    1\n   x  = "+L(x2r,x2i)+"\n    2\n   x  = "+L(x3r,x3i)+"\n    3\n   x  = "+L(x4r,x4i)+"\n    4\n\n";
	}
	if((ERL)&&(B==0)&&(D==0))
	{
		txt+=ustr+"\n\nEs ergaben sich also die Lösungen\n\n   y  = x²  = "+L(xq1r,xq1i)+"\n    1    1\n\n   y  = x²  = "+L(xq2r,xq2i)+"\n    2    2\n\n"; 
		txt+="Da die ursprüngliche Gleichung mit y = x² substituiert wurde, gewinnt man x aus\ndiesen Lösungen mit x = sqr(y). ";
		txt+="Hierbei ist zu beachten, daß die Wurzel eine positive\nund eine negative Lösung hat; mithin verdoppelt sich gegebenenfalls die Zahl der \nLösungen. \n\n";
		txt+="   x  = + sqr("+L(xq1r,xq1i)+")\n    1\n\n   x  = - sqr("+L(xq1r,xq1i)+")\n    2\n\n   x  = + sqr("+L(xq2r,xq2i)+")\n    3\n\n   x  = - sqr("+L(xq2r,xq2i)+")\n    4\n\n";
		txt+="Möglicherweise ist die Reihenfolge der Lösungen in der obigen Liste anders, denn \nder Spezialfall b=0 und d=0 wird nicht besonders behandelt, ";
		txt+="sondern nach dem \nallgemeinen Verfahren gelöst. Daher werden die Lösungen hier auch nicht zahlenmäßig \nangegeben. \n";  
	}
	return 4;
}

function WurzelProdukt(W1r,W2r,W3r,W1i,W2i,W3i,i1,i2,i3)
{
	return L(W1r[i1]*(W2r[i2]*W3r[i3] - W2i[i2]*W3i[i3]) - W1i[i1]*(W2r[i2]*W3i[i3] + W2i[i2]*W3r[i3]) ,(W1r[i1]*(W2r[i2]*W3i[i3] + W2i[i2]*W3r[i3]) + W1i[i1]*(W2r[i2]*W3r[i3] - W2i[i2]*W3i[i3])));
}

function SIGN(x){if(x>0)return 1;if(x==0){return 0;}return -1;}

function CheckGanzzahl(a,b,c,d,xr)
{
	var X=Math.floor(xr +.1);
	if (X*(X*(a*X+b)+c)+d==0) return X; else return xr;
}
function CheckDez(a,b,c,d,xr,dez)
{
	var X=Math.floor(xr*dez +.5)/dez;
	//alert(X+"\n"+xr+"\n"+(X*(X*(a*X+b)+c)+d));
//	if (Math.abs(X*(X*(a*X+b)+c)+d)>0.00001) alert("Fehler: y="+Math.abs(X*(X*(a*X+b)+c)+d));
	if (Math.abs(X*(X*(a*X+b)+c)+d)<1/dez) return X; else return xr;
}

function CheckDez4(a,b,c,d,e,xr,dez)
{
	var X=Math.floor(xr*dez +.5)/dez;
	//alert(X+"\n"+xr+"\n"+(X*(X*(a*X+b)+c)+d));
	if (Math.abs(X*(X*(X*(a*X+b)+c)+d)+e)>0.001) alert("Fehler: y="+Math.abs(X*(X*(X*(a*X+b)+c)+d)+e));
	if (Math.abs(X*(X*(X*(a*X+b)+c)+d)+e)<1/dez) return X; else return xr;
}


function CheckKomplex(a,b,c,d,e,xr,xi)
{
//          a·(i^4 - 6·i^2·r^2 + r^4) + b·r·(r^2 - 3·i^2) + c·(r^2 - i^2) + d·r + e 
//	      - i·(4·a·r·(i^2 - r^2) + b·(i^2 - 3·r^2) - 2·c·r - d)
	var xr2=xr*xr,xr3=xr2*xr,xr4=xr2*xr2,xi2=xi*xi,xi3=xi2*xi,xi4=xi2*xi2;
	ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
	ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
	return( ch_re*ch_re+ch_im*ch_im);
}

function test(a,b,c,d,e,g)
{
	document.f.tx1.value="";
	document.f.tx2.value="";
	document.f.tx3.value="";
	document.f.tx4.value="";
	var xr=x1r,xi=x1i,xr2=x1r*x1r,xr3=xr2*x1r,xr4=xr2*xr2,xi2=x1i*x1i,xi3=xi2*x1i,xi4=xi2*xi2;
	ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
	ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
	document.f.tx1.value=L(ch_re,ch_im);if(xr2="")return;
	xr=x2r,xi=x2i,xr2=x2r*x2r,xr3=xr2*x2r,xr4=xr2*xr2,xi2=x2i*x2i,xi3=xi2*x2i,xi4=xi2*xi2;
	ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
	ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
	document.f.tx2.value=L(ch_re,ch_im);if(g==2)return;
	var xr=x3r,xi=x3i,xr2=x3r*x3r,xr3=xr2*x3r,xr4=xr2*xr2,xi2=x3i*x3i,xi3=xi2*x3i,xi4=xi2*xi2;
	ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
	ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
	document.f.tx3.value=L(ch_re,ch_im);if(g==3)return;
	var xr=x4r,xi=x4i,xr2=x4r*x4r,xr3=xr2*x4r,xr4=xr2*xr2,xi2=x4i*x4i,xi3=xi2*x4i,xi4=xi2*xi2;
	ch_re=a*(xi4 - 6.0*xi2*xr2+xr4)+b*xr*(xr2-3.0*xi2)+c*(xr2-xi2)+d*xr+e;
	ch_im=-xi*(4.0*a*xr*(xi2-xr2)+b*(xi2-3.0*xr2)-2.0*c*xr-d);
	document.f.tx4.value=L(ch_re,ch_im);
}



function Runden_(x)
{
	var xx=String(x);
	if ((xx.indexOf("000000000")>=0)||(xx.indexOf("999999999")>=0)) x=Math.round(x*100000000)/100000000;
	if(Math.abs(x)<1.0e-20)x=0;
	return x;
}

function sgn(x){if(x>0)return 1; else if(x<0)return -1; else return 0;}

function sqrk(a,b,wr,wi)
{
	var w=Math.sqrt(a*a+b*b),c=Math.sqrt((w+a)/2),d=Math.sqrt((w-a)/2);
	if(b<0)d=-d;
	wr[0]=-c;wi[0]=-d;
	wr[1]=c;wi[1]=d;
	//alert("sqr("+L(a,b)+")\n = \n"+L(c,d)+"\n oder\n"+L(-c,-d));
	//alert("real: "+a+" = "+(c*c-d*d)+"\nimag: "+b+" = "+2*c*d);
}
