reptile7's JavaScript blog
Friday, July 24, 2020
A Whole or Fractional power( )
Blog Entry #411

We return now to our run through the Super Calculator's exponentiation landscape. With all that prompt( )ing in the power( ), squared( ), and cubed( ) functions, it occurred to me that we should talk about the a and b data types a bit before we go any further...

xy input audit

For our 97 exponentiation in the previous post, the a = 9 and b = 7 inputs actually have a string data type: at Math.pow(a, b) time, the 9 and 7 operands are converted to numbers.

"" and null

If we leave a prompt( ) inputDefault field blank

Enter an exponent:

and click the button, then the prompt( ) output is the empty string; if we click the button, then the output is null (the primitive value vs. as a string). When plugged into a Math.pow( ) command, "" and null both convert to 0. FYI: Math.pow(0, 0) returns 1 even though 00 has no agreed-upon value.

Non-empty, non-numeric

Suppose we type hello in the total field (the total field is not readonly, we can do that) and try to raise it to the world power: as you would expect, helloworld returns NaN. Such inputs can be intercepted via an iterative isNaN( ) test (admittedly at the risk of annoying the user), e.g.:

b = window.prompt("Enter an exponent:", "");
while (isNaN(b)) { b = window.prompt("Your exponent must be a number:", ""); }


In the C/d section of Blog Entry #409 we learned that the SC's key outputs a Math.PI.toFixed(15) value surrounded by parentheses. The ( and ) characters prevent the conversion of the (3.141592653589793) string to a number for an exponentiation (or trigonometric) operation; as a result, Math.pow("(3.141592653589793)", b) returns NaN for all b except b = 0, for which the return is 1. We can easily lose the ( ) by pressing the key, i.e., eval("(3.141592653589793)") returns 3.141592653589793 (as a number, which is stringified when written to the total field), after which we can raise the pi value to whatever power we want.

Root extraction

Root extraction can be expressed exponentially: finding the yth root of some number x is equivalent to raising x to the 1/y power.

We can use the original power( ) function to calculate a x1/y root as long as the 1/y exponent is in decimal form: b = 0.5 for a square root, b = 0.25 for a 4th root, etc. As you would intuit from the preceding (π) discussion, a 1/y string's / character prevents its Math.pow( ) numberification.

If we don't know 1/y's decimal equivalent, then we can divide 1 by y in advance, copy the quotient to the clipboard, and paste the quotient into the Enter an exponent: inputDefault field when the time comes. As it happens, however, any numerator/denominator-type fraction can be eval( )ed to its decimal equivalent - cf. the SC's calc( ) function - so if we insert an
if (/^1\/\d+$/.test(b)) b = eval(b); statement* after each
b = window.prompt("Enter an exponent:", ""); statement,
then we can input 1/y itself into the inputDefault field.
*The /^1\/\d+$/ regexp pattern matches a 1/y string whose y character is an unsigned integer; we'd need a more complex pattern to additionally accommodate other ys.

So now, if we want to find the 7th root of 9 (maybe you would know that 1/7 = 0.14285714285714285, but I wouldn't), we're all set.

My Casio fx-85v calculator has an x1/y function, which is accessed via SHIFT-ing the key. We have the option of putting a image on a push button:

<button type="button" onclick=""><img width="" height="" style="" src="pathname/yth_root_of_x2.gif" alt="" /></button>

In creating the yth_root_of_x2.gif image, I gave the x and y a 16px/13px default/<sup> font-size ratio.

You're so square root, baby

The SC's Misc section has a dedicated button

<input type="button" value="Sqrt" onclick="getinput(squareroot);">

for getting the square root of a number. The button is bound to a squareroot( ) function that is called from the getinput( ) function à la the power( ), squared( ), and cubed( ) functions.

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

The squareroot( ) function is detailed below; Mozilla's current Math.sqrt( ) page is here.

function squareroot(mode, obj) {
    if (mode == 1) { window.alert("This function gives you the square root of any given number"); }
    if (obj.value != "" && obj.value != "0") {
        aa = window.prompt("Do you want to find the square root of the current number in the total text box?", "y or n");
        if (aa == "y") { doit(Math.sqrt(obj.value), obj); }
        else {
            a = window.prompt("Enter a number to find the square root of:", "");
            more("(" + Math.sqrt(a) + ")", obj); } }
    else {
        a = window.prompt("Enter a number to find the square root of:", "");
        doit(Math.sqrt(a), obj); } }

I gave you a detailed power( ) deconstruction earlier, do we need to do the same thing here? Nah, let's go with a quick post-mode rundown:
(1) If the total.value isn't empty or 0 - if we've entered something into the total field, not necessarily a number - then we are prompt( )ed to confirm (y or n) that we want to square-root the entered value.
(a) If y, then the total.value is square-rooted and the resulting square root is written to the total field via the doit( ) function.
(b) If not y, then we are prompt( )ed for a new value to square-root; the a prompt( ) output is square-rooted and (a1/2) is appended to the total.value via the more( ) function.
(2) If the total.value is empty or 0, then we are prompt( )ed for a value to square-root; the a prompt( ) output is square-rooted and a1/2 is written to the total field via the doit( ) function.

If the SC's mode help flag is turned on (1), then we'll get a
This function gives you the square root of any given number alert( ) message
before the if tests and prompt( )ing get under way. The message could be a bit more specific: we all know that we can't take the square root of a negative number...or can we? Actually, we addressed the calculation of imaginary square roots in the It's complex section of Blog Entry #344 during our analysis of the CCC Quadratic Equation script; for the SC the corresponding code could go something like:

var radicand = Number(x); // x = obj.value or a
if (radicand < 0) {
    var real_root = Math.sqrt(-radicand);
    var imag_root = "i \u00d7 " + real_root;
    obj.value = imag_root;
    return; }

Otherwise, Math.sqrt(x) returns NaN if x cannot be converted to a nonnegative number;
per the Non-empty, non-numeric subsection above,
a while (isNaN(x) || x < 0) { x = window.prompt("Your radicand must be a nonnegative number.", ""); }-type statement
can be used to intercept problematic Math.sqrt(x) inputs.

Apropos asides:

Jamie Beyore's Another Great Science Calculator has a key that executes
an external function calc_sqrt(form) { form.expr.value = (Math.sqrt(form.expr.value)) } function whereas
Saries's Rainbow Calculator has an (unsuperscripted) key that executes
an inline document.calculator.text.value = Math.sqrt(document.calculator.text.value) statement.

A standard calculator won't calculate imaginary square roots (at least my Casio won't), but if you go to Google and enter
What is the square root of -9?
in the search field and then click your keyboard's Enter/Return key, you'll get a new page with a
square root(-9) = 3i

div near the top of it.
We'll cover the SC's and functionality in the following entry.

Powered by Blogger

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