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
Help message reads:

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

Powered by Blogger

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