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 a⋅b^{c}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 = b

^{c}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 productor

the

`more( )`

function so as to append a (a*d) string to the total.value.**Exponentiation consolidation**

The use of separate functions for the x

^{2}, x

^{3}, and x

^{y}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 codeand 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 = x

^{y}relation we have calculated

z by raising x to the y

^{th}power and

x by extracting the y

^{th}root of z.

In this section we go after y, the base-x logarithm of z: y = log

_{x}(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 subsequentlyan

`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 log

_{x}(z) = log

_{e}(z) / log

_{e}(x) change-of-base logarithm formula to get logarithms for bases other than the standard ones. The x

^{y}and log

_{x}(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

^{iπ}= -1 case of the Euler formula.

For the natural log of a negative number

ln(-z) = ln(z) + iπ

whereas for the general base-x case

log

_{x}(-z) = (ln(z) + iπ) / 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 = log

_{1}(z) and y = log

_{0}(z) are not meaningful functions: z must necessarily be 1 and 0, respectively, whereas y can be any number.

For the above y = log

_{x}(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.

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