reptile7's JavaScript blog
Thursday, June 25, 2020
 
And You, Be Ye Fruitful, and Exponentiate
Blog Entry #410

In the Arithmetic action section of the previous post we used the Super Calculator to add 9 and 7. As we can all add 9 and 7 in our heads without the aid of a calculator, let's up our game by using the SC to raise 9 to the 7th power.

97

We enter a 9 into the total field via the button and the more( ) function as described earlier. We click the button in the SC's Powers section

<td><b>Powers:</b><br>
...
<input type="button" value=" x^y " onclick="getinput(power);">


thereby calling the getinput( ) function and passing thereto a power function reference. I'm not going to put the entire getinput( ) function in front of you (see the whole thing here); the relevant part of it for our present purpose is:

function getinput(func) {
    var a = document.mainform.total;
    if (document.mainform.mode[0].checked) { var mode = 1; } // Help mode
    else { var mode = 0; } // Non-help mode
    if (func == power) { return power(mode, a); } ...


The power argument is given a func identifier.

The total Text object is assigned to an a variable - how's that for a descriptive name? - I'd call it calcText or something like that.

A mode variable is set to 1 if the
Help radio button is checked or to 0 if the
No Help radio button is checked; a conditional (ternary) var mode = document.mainform.mode[0].checked ? 1 : 0; statement can be used here.

The <script>'s power( ) function is called if func and power are equal - true in this case.
Here is the power( ) function from start to finish:

function power(mode, obj) {
    if (mode == 1) { window.alert("Power allows you to give powers to any given number."); }
    if (obj.value != "" && obj.value != "0") {
        aa = window.prompt("Do you want to use the number in the total textbox as the base number?", "y or n");
        if (aa == "y") { a = obj.value; }
        else { a = window.prompt("Enter a base number:", ""); }
        b = window.prompt("Enter an exponent:", "");
        if (aa == "y") { doit(Math.pow(a, b), obj); }
        else { more("(" + Math.pow(a, b) + ")", obj); } }
    else {
        a = window.prompt("Enter a base:", "");
        b = window.prompt("Enter an exponent:", "");
        doit(Math.pow(a, b), obj); } }


The mode number and the a object are passed to the power( ) function and are given the identifiers mode and obj, respectively.

The power( ) function checks if the mode help flag is turned on (it's initially on, as was noted earlier, although you are free to turn it off, of course) and if so displays a
Power allows you to give powers to any given number alert( ) message.
The author/Webmaster sees the [p]ower identifier but the user doesn't, and I would recast the message as:
The x^y key allows you to raise a base number x to the yth power.

The power( ) function tests
if the obj.value is not the empty string AND (&&)
if the obj.value is not the numeric string "0"
and if both conditions are met - our 9 fits the bill, yes? - displays a prompt( ) box that asks us if we want to use the number in the total field for the x base number, which strikes me as an odd sort of thing for a calculator to do, but that's what happens.

Do you want to use the number in the total text box as the base number?
(Now that I think about it, this sort of message belongs on a confirm( ) box.)

As shown above, the default value of the prompt( ) input field (termed the inputDefault back in the day) is set to a y or n string. Some browsers (e.g., Firefox/Netscape, Opera, Safari) select the string: if we're using such a browser, then we can convey our 'yes' by simply pressing the keyboard's y key. The y value is assigned to an aa variable upon clicking the prompt's button.

The power( ) function tests if aa is y - true - and then assigns the obj.value, 9, to an a variable: this a has a global scope because it is not declared with the var keyword (ditto for the above aa variable and the b variable below) and it is wholly distinct from the getinput( ) function's a, which is declared with the var keyword and is therefore local to the getinput( ) function, not that it would make a difference if the former a superseded the latter a.

The power( ) function displays a prompt( ) box that instructs us to enter an exponent, so we type a 7 in the prompt( ) input field. The 7 value is assigned to a b variable upon clicking the prompt's button.

The power( ) function again tests if aa is y - still true - and then
exponentiates a to the bth power via the pow( ) method of the Math object and
sends the ab power, 4782969, and the obj reference for the total field to the doit( ) function,
which we discussed in the Roundabout rounding section of the previous post and
which writes the ab power (renamed obj by the doit( ) declaration) to the total field (renamed where by the doit( ) declaration).

We're not quite done yet. Moving back to the getinput( ) function, note that the power( ) call is preceded by a return keyword, which causes the browser to exit the getinput( ) function after the power( ) function has finished executing. (The aforediscussed doit( ) call is neither preceded nor followed by a return keyword, and the power( ) function returns undefined to the getinput( ) function.)

Two other power( ) possibilities, briefly

If the obj field holds the starting 0 or has been backspaced to a blank,
then the power( ) function will
prompt( ) us for a base (a),
prompt( ) us for an exponent (b), and
raise a to the bth power and load the ab power into the where field via the doit( ) function as described above.

If we do not answer y to the
Do you want to use the number in the total textbox as the base number? prompt
(leaving the y or n inputDefault in place counts as not answering y),
then the power( ) function will
prompt( ) us for a base number (a),
prompt( ) us for an exponent (b), and
raise a to the bth power and wrap the ab power in parentheses and ship the (ab) string and the obj reference to the more( ) function, whose else clause will append the (ab) string to whatever is present in the total field.



Got all that? Quite a bit more involved than the corresponding

function raisePower(x) {
    var y = 0;
    y = window.prompt("What is the exponent?", "");
    document.calculator.text.value = Math.pow(x, y); }


in Saries's Rainbow Calculator script, isn't it?

Squaring and cubing

We can use the button to raise a base number to the 2nd or 3rd power; however, the Powers section has dedicated and buttons

<input type="button" value=" ^2 " onclick="getinput(squared);">
<input type="button" value=" ^3 " onclick="getinput(cubed);">


for these operations. The and buttons are bound respectively to squared( ) and cubed( ) functions that are called from the getinput( ) function à la the power( ) function

if (func == squared) { return squared(mode, a); }
if (func == cubed) { return cubed(mode, a); }


and that are largely analogous to the power( ) function, more specifically, they're a bit simpler than power( ) in that they don't need to get an exponent from the user.

Exponentiation button labels, revisited

A coder will know that the ^ symbols signify exponentiations, but will an ordinary user know that? The Powers heading and the
Help help messages are not an adequate substitute for seeing actual exponents on the Powers buttons, in my opinion.

The button exponent blues, at least for Netscape

The Latin-1 Supplement Unicode block contains a ² superscript two character and a ³ superscript three character, whose HTML numeric character references are &#178; and &#179;, respectively. I find that Navigator 4.05 (recall the SC's best used with Netscape Communicator 4.0 metatext) will not render these characters, e.g., it renders <input type="button" value="x&#179;"> as versus . Meanwhile, the Spacing Modifier Letters Unicode block contains a ʸ superscript y character (&#696;, thanks, Rupert); as you might guess, Navigator 4.05 won't render that one either.

• Level 4 and earlier browsers will display most of the 'upper Latin-1' characters - ©, é, ü, ÷, ... - but they can't handle the ² and ³ or can't quite handle them, e.g., IE 4.5 displays them as normal 2 and 3 characters and not as superscripts.
• The ², ³, and ʸ characters all appeared in Unicode 1.0.0, the very first version of Unicode, which went live in October 1991.

At the beginning of Blog Entry #75 I mooted the use of graphical submit buttons for calculator keys whose labels feature uncodable symbols - would this approach have worked for the Powers buttons way back when? I accordingly create
an x_to_the_yth.gif image
(I clip it from a screen shot, Netscape 4.x's buttons have a #dddddd background color)
and buttonize it via
<input name="power_gsb" type="image" src="x_to_the_yth.gif" onclick="getinput(power);">.
In the event:
With Navigator 4.05, clicking the power_gsb button does not trigger the getinput( )/power( ) code but it does cause the mainform form to submit; the latter action can be choked off by giving the form an onsubmit="return false;" attribute.
With IE 4.5, the power_gsb button is invisible until I give it some sort of styling* - even an otherwise effectless style="display:inline;" will do - but upon doing that and clicking the button, the getinput( )/power( ) code runs without incident. (*I don't know if this is a browser/plug-in bug or an artifact of my SheepShaver setup - this page makes me suspect the former.)

• The <input type="image"> element has no reflection in classical JavaScript; it should map to the Submit object, but it doesn't. Btw, an <input type="submit" value="x^y" onclick="getinput(power); return false;"> button works just fine.

Of course, we would today deploy <button type="button">x<sup>n</sup></button> buttons in the Powers section. Navigator 4.05 supports the sup element but not the button element; IE 4.5 supports both elements.

A buttonless workaround

The following code works with Navigator 4.05 and IE 4.5 and also with Navigator 3.04 and Communicator 4.61 and IE 5.1.7 and modern browsers:

<a href="" onclick="getinput(power); return false;" style="display:inline;"><img width="21" height="18" border="1" src="x_to_the_yth.gif" alt=""></a>

A graphical submit button may be a problematic onclick carrier, but there are no problems with a corresponding link carrier. As a general rule, I don't like to use a link for a non-linking purpose, but a coder's gotta do what a coder's gotta do, eh?

• The link href is set to an empty string, which would normally cause a page reload when we click the link-image, but we can stop that from happening with a return false too.
• Per the preceding subsection, the style="display:inline;" is for IE 4.5's benefit; none of the other browsers needs it.
• Attaching the style="display:inline;" to the <img> element gives rise to some bizarre image-moving behavior with Navigator 4.05 and Communicator 4.61 - I'll spare you the details.
• A style="position:relative;" visualizer, which should also be effectless, causes Navigator 4.05 and Communicator 4.61 to crash.
There are actually three other SC keys that relate to exponentiation - , , and - and we'll discuss them and their underlying functions in our next episode.


Powered by Blogger

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