reptile7's JavaScript blog
Sunday, February 15, 2015
 
Hitting the X Axis
Blog Entry #343

In today's post, we will use the JavaScript Goodies Quadratic Equation script to solve the equation 2x2 - 5x - 4 = 0. You may follow along via this demo (thanks, Dana); in case you were wondering, the equation has real roots but you won't be able to factor it.

When the quad.html page has finished loading

<body bgcolor="#000000" onload="qform.a.focus( );">

focus is given to the qform form's a (Variable a) field. The JavaScript Goodies "Clocks, Calculators, and Calendar Scripts" page warns that the Quadratic Equation script requires MSIE; the qform.a.focus( ); operation and others like it we'll encounter below throw a qform is not defined error with Netscape 4.x. However, quashing the error is no more difficult than prepending document. to the qform form reference.

We enter 2 into the a field

<input class="text" type="text" size="7" maxlength="7" name="a" onchange="checka( );" style="text-align:center;" title="Input the value of the variable a here.">

and hit the tab key to move to the corresponding b (Variable b) field. Changing the a value calls the checka( ) function in the script17.js script in the quad/ package.

function checka( ) { var a = qform.a.value; if (isNaN(a)) { if (window.confirm("You have inputted an invalid number for the variable a. Begin again?")) { over( ); } else { location.href = "index.html"; } } }

The checka( ) function gets the qform.a.value, which has a string data type, and assigns it to an a variable. The a value is fed to the top-level isNaN( ) function to see if it is NaN (Not-A-Number): for our example, the "2" string is converted to a numeric 2, the isNaN(a) operation returns false, and the function exits.

But suppose we enter hi into the a field. In this case, the isNaN(a) operation returns true and the browser pops up a confirm( ) box bearing a "You have inputted an invalid number for the variable a. Begin again?" message.



Clicking the box's button takes us to the index.html page of the current directory. Clicking the box's button calls the script17.js over( ) function.

function over( ) { qform.a.value = ""; qform.b.value = ""; qform.c.value = ""; qform.x.value = ""; location.reload( ); qform.a.focus( ); }

The over( ) function sets the values of the a, b, c, and x fields of the qform form to empty strings, reloads the page, and returns focus to the a field.

Noteworthily, the checka( ) function does not stop us from
(a) setting the a value to 0 or
(b) leaving the a field blank: the empty string converts to 0 for an isNaN( ) operation.
We'll address these possibilities in a little bit.

Moving on, we enter -5 into the b field

<input class="text" type="text" size="7" maxlength="7" name="b" onchange="checkb( );" style="text-align:center;" title="Input the value of the variable b here.">

and hit the tab key to move to the corresponding c (Variable c) field. Changing the b value calls the script17.js checkb( ) function, which does for the qform.b.value what the checka( ) function does for the qform.a.value. We enter -4 into the c field

<input class="text" type="text" size="7" maxlength="7" name="c" onchange="checkc( ); process( );" style="text-align:center;" title="Input the value of the variable c here.">

and hit the tab key to move to the x (Resultant value of x) field. Changing the c value calls two script17.js functions:
(1) checkc( ), which does for the qform.c.value what checka( ) does for the qform.a.value and checkb( ) does for the qform.b.value, and
(2) process( ), which solves the 2x2 - 5x - 4 = 0 equation and displays its roots in the x field.

The process( ) function initially looks at the a/b/c fields to see if any of them have been left blank: if true, then it either calls the over( ) function to clear the a/b/c/x fields or sends us to the index.html page à la the checka( )/checkb( )/checkc( ) functions.

function process( ) { var a = qform.a.value; if (a == "") { if (window.confirm("You have entered an invalid number. Begin again?")) { over( ); } else { location.href = "index.html"; } } var b = qform.b.value; if (b == "") { if (window.confirm("You have entered an invalid number. Begin again?")) { over( ); } else { location.href = "index.html"; } } var c = qform.c.value; if (c == "") { if (window.confirm("You have entered an invalid number. Begin again?")) { over( ); } else { location.href = "index.html"; } }

Assuming that everything is OK, we next plug the a/b/c values into the quadratic formula.

The quadratic formula

var num = ((b * b) - (4 * a * c));
num = Math.sqrt(num); // Returns NaN if the num difference is a negative number.
var den = (a * 1) + (a * 1); // Could we just multiply a by 2 here? Yeah, we could.
var plus = (-b) + (num);
var minus = (-b) - (num);


We square b and subtract 4ac and take the square root of the difference; the num root is added to and subtracted from -b. Meanwhile, a is doubled.

plus = (plus / den); if (isNaN(plus)) { if (window.confirm("You have entered values which resulted in a negative square, an uncalculable constant. The solution is NO SOLUTION. Begin again?")) { over( ); } else { location.href = "index.html"; } } minus = (minus / den);

The plus and minus numerators are divided by the den denominator. The plus quotient is isNaN(plus)ed so as to check if the b2 - 4ac difference is a negative number; if true, then a "the roots aren't real" confirm( ) box pops up (that's not quite what it says, but that's the underlying idea).



As before, clicking the box's button clears the a/b/c/x fields via the over( ) function and clicking its button takes us to the index.html page.

The plus quotient is also NaN if a is 0, so we choke that situation off as well.

For our example,
b2 - 4ac = (-5)2 - 4(2)(-4) = 57 and
a = 2 and therefore
isNaN(plus) returns false,
so we move to the process( ) function's last four commands:

var denum = "" + plus + " or " + minus + ""; // The empty strings at the beginning and the end are unnecessary.
qform.x.value = denum;
qform.a.select( );
qform.a.focus( ); } // That's it for process( ).


The plus quotient, an " or " string, and the minus quotient are concatenated and the resulting string is loaded into the x field.

<input class="text" type="text" size="30" maxlength="30" name="x" readonly="readonly" style="text-align:center;" title="Resultant value of variable x.">

Our denum solution is:
3.1374586088176875 or -0.6374586088176875
This value is not truncated by the maxlength="30" setting although we don't see the whole thing due to the input size="30".

Subsequently, the 2 in the a field is selected and focus is returned to the a field, focus in this case meaning a focus rectangle and not a blinking insertion point. (FWIW: The browsers on my computer do not cleanly separate the select and focus events. If the focus( ) command is commented out and the a field's 2 is select( )ed, then typing x still inputs x into the a field.)

Button functions

At any time during the process, we can clear the a/b/c/x fields via the over( ) function by clicking the button

<input class="button" type="button" value="Reset!" onclick="over( );">

or pop up a help message via the script17.js help( ) function by clicking the button.

<input class="button" type="button" value="Help!" onclick="help( );">

The help( ) function

function help( ) { window.alert(" ©1998 Sam ß. Lachterman\n - Use the Tab button on your keyboard to switch between fields.\n - Enter the value of a.\n - Enter the value of b.\n - Enter the value of c.\n - The rest will be done for you!"); }

displays:



Re the alert( ) string:
• The literal © character should be encoded as a \u00A9 Unicode escape sequence.
• Sam specifies his S middle initial as a literal ß (eszett) character, which is rendered as a § (section sign) character on the alert( ) box - let's just use a regular S here, shall we?
• Line breaks are induced by the \n special character.

In the following entry, we'll revamp the quad.html/script17.js code a bit and if that doesn't take too long we'll also look at an equation example having complex roots.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)