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 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.