reptile7's JavaScript blog Sunday, December 27, 2020

Power, Base, and Logarithms
Blog Entry #412

Today's Super Calculator (SC) installment begins with a brief look at an exponentiation-related operation that I've never heard of before...

Special, or not

The Special functions section on the left-hand side of the calculator contains a button.

`<input type="button" value="Spec" onclick="getinput(spec);">`

Clicking the button indirectly triggers a `spec( )` function whose verbatim

`"Spec is handy tool that allows you to multiply a number by another number any number of times. It works kind of like powers, except the only difference is that in powers, you have multiply a number by itself any number of times. This function allows you to multiply any number by any number, any number of times."`

(Would you as a user want to read all that? I wouldn't.)
The `spec( )` function carries out an abc calculation, i.e., it multiplies an a factor by a b factor c times. If you are perchance thinking "This is nothing that can't be done with the SC keys we've covered previously", well, you would be right about that.

Like the other exponentiation functions, the `spec( )` function is actually called from the `getinput( )` function.

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

The `spec( )` function is the ninth-in-source-order function in the supercalc.txt `<script>` element and is similar to the `power( )` function.
It `prompt( )`s the user for the a, b, and c operands.
A `d = Math.pow(b, c);` command raises b to the c power.
The d = bc power is multiplied by a.
Depending on the starting point of the calculation, control then passes to either
the `doit( )` function so as to set the total.value to the a*d product
or
the `more( )` function so as to append a (a*d) string to the total.value.

Exponentiation consolidation

The use of separate functions for the x2, x3, and xy operations is rather inefficient, yes? We can straightforwardly rewrite the `squared( )`, `cubed( )`, and `power( )` functions as a single function - let's call it `getPower( )` - if we equip that function with a third, b = 2 or 3 or y parameter for the exponentiation exponent. We can discretely bind the , , and buttons to the `getinput( )` gateway with simple strings versus the squared, cubed, and power references for the functions we are putting out to pasture.

```if (func == "square") { return getPower(mode, a, 2); } if (func == "cube") { return getPower(mode, a, 3); } if (func == "power") { return getPower(mode, a, "y"); } function getPower(mode, obj, b) { /* getPower( ) body */ } <button type="button" onclick="getinput('square');">x<sup>2</sup></button> <button type="button" onclick="getinput('cube');">x<sup>3</sup></button> <button type="button" onclick="getinput('power');">x<sup>y</sup></button>```

The `getPower( )`
Help messages can be gathered and conditionalized via a series of if gates

```var alert_message; if (mode) {     if (b == 2) alert_message = "This key allows you to square any given number.";     if (b == 3) alert_message = "This key allows you to cube any given number.";     if (b == "y") alert_message = "This key allows you to raise a base number x to the yth power.";     window.alert(alert_message); }```

or a switch statement.

```if (mode) {     switch (b) {         case 2: alert_message = "This key allows you to square any given number."; break;         case 3: alert_message = "This key allows you to cube any given number."; break;         case "y": alert_message = "This key allows you to raise a base number x to the yth power."; }     window.alert(alert_message); }```

(I would prefer to display `"The xⁿ key allows you to..."` alert_messages but their rendered exponents are too small for my taste.)

For the `getPower( )` function's post-help code,
just if-gate the exponent `prompt( )`s in the relative `power( )` function code
and you've got what you need:

```var aa, a; if (obj.value != "" && obj.value != "0") {     aa = window.prompt("Do you want to use the number in the total text box as the base number?", "y or n");     a = (aa == "y") ? obj.value : window.prompt("Enter a base number:", "");     if (b == "y") 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:", "");     if (b == "y") b = window.prompt("Enter an exponent:", "");     doit(Math.pow(a, b), obj); }```

It is left to the reader to integrate the `spec( )` function with the `getPower( )` function, if desired; as intimated above, however, the operation is redundant in my view and I would just as soon send it packing.

Log it

As regards the z = xy relation we have calculated
z by raising x to the yth power and
x by extracting the yth root of z.
In this section we go after y, the base-x logarithm of z: y = logx(z).

The Special functions section contains a button (versus a button) for getting the base-e natural logarithm of a number.
Clicking the button effects
an `onclick="getinput(logrythm);"` event handler (sic, perhaps the author typed up the code with SimpleText, which does not have a spell checker) and subsequently
an `if (func == logrythm) { return logrythm(mode, a); }` statement in the `getinput( )` function
à la the exponentiation buttons.

The `logrythm( )` function is the fourteenth-in-source-order function in the supercalc.txt `<script>` element and closely parallels the `squared( )` and `cubed( )` functions: it replaces the latter's Math.pow(x, y) commands with Math.log(z) commands and has its own `"This function returns the natural logarythm [sic again] of any given number"`
Help message but apart from that their other features (if and if...else gates, variable names, `doit( )` and `more( )` calls) are identical.

Other calculators, other bases

Jamie Beyore's Another Great Science Calculator features a button for getting the common logarithm of a number and a button for getting the binary logarithm of a number.
Saries' Rainbow Calculator doesn't have any logarithm buttons at all.
Standardly, my Casio fx-85v calculator has a key for getting the common logarithm of a number and a key for getting the natural logarithm of a number.

Meanwhile, back at the SC, why should we limit ourselves to base-e (or base-10 or base-2) logarithms? In the Logarithms section of Blog Entry #370 we noted that we can use the logx(z) = loge(z) / loge(x) change-of-base logarithm formula to get logarithms for bases other than the standard ones. The xy and logx(z) calculations both take two inputs, and it occurred to me that the original `power( )` function should be easily convertible to a `getLog( )` function for the latter calculation: all we need to is
(1) craft a new
Help message (`"This key allows you to find the logarithm of a number z for the base x of your choosing."`, something like that),
(2) reword the operand `prompt( )`s as appropriate (`"Enter an anti-logarithm z:"`, `"Enter a base x:"`), and
(3) replace the `Math.pow(a, b)` commands with `Math.log(a)/Math.log(b)` commands.

Try it out below - re the text box, you can start from or blank the starting 0, or enter your own input - for best results, your z and x choices should be positive numbers other than 1.

Unreal cases

Math.log(0) returns -Infinity (rather than undefined).

Math.log(-z) for -z < 0 returns NaN. In the You're so square root, baby subsection of Blog Entry #411 we reached beyond the real number system to take the square root of negative numbers, and we can similarly take the logarithm of negative numbers via the e = -1 case of the Euler formula.
For the natural log of a negative number
ln(-z) = ln(z) +
whereas for the general base-x case
logx(-z) = (ln(z) + ) / ln(x).
(Btw, Google will calculate the former for you - What is the natural log of -47? - but not the latter.)
I trust that you are up to the task of JavaScripting these expressions.

y = log1(z) and y = log0(z) are not meaningful functions: z must necessarily be 1 and 0, respectively, whereas y can be any number.
For the above y = logx(z) = ln(z) / ln(x) demo
an x = 1 input variously outputs y = Infinity, -Infinity, or NaN whereas
an x = 0 input variously outputs y = 0 or NaN
depending on the z input, e.g., if 1 < z, if 0 < z < 1, etc.

Can the logarithm base x itself be negative? The answer is basically yes, but it's not generally very useful - let's leave it at that.
We'll discuss the SC's trig functions in the next entry.