Simple Scientific calculator for ADE, the UNIX environment for the AMIGA A1200(HD).

ADE is a UNIX environment for the ancient AMIGA A1200. By default this does NOT have the 'bc' command line calculator.
Although I did a DEMO code to create a C source and compile it under python 1.4.0 and ADE using ksh88 and the gcc of the day, I decided to create this baby that requires no Python and compilation at all. 'bc' can be obtained from AMINET but is is so convoluted that I don't use it.

This incarnation uses 'awk' purely as a calculator for complex floating point, (basic scientific), calculations and is a shell script.
This was developed on this MBP OSX 10.14.3 and tested in the AMIGA environment using the above.

#!/bin/sh

# #!/usr/local/bin/dash
# scicalc

# USAGE 1: All methods: [/full/path/to/|./]scicalc ['|"]expression_inside_quotes["|']<CR>
# USAGE 2: In a script: VAR='expression'; ./scicalc "${VAR}"<CR>
# Which quotes depends on the situation, "${VAR}" as an expression variable is valid '${VAR}' is invalid.

# All angular expressions are in radians!
expression="$1"

# Don't allow an empty "$1".
if [ "${expression}" = "" ]
then
    echo "Basic USAGE: [./]scicalc [']"'["]''expression_inside_quotes''["]'"[']""<CR>"
    echo "!!!Read the code for more information!!!"
    exit 1
fi

# Minimum awk Version tested on:
# GNU Awk 3.0.3.
# For the AMIGA A1200(HD) OS3.0.x, running ADE, the UNIX environment using ksh88 as the shell.
#
# Developed on OSX 10.14.x, "awk version 20070501".
awk 'BEGIN{ pi=3.141592653589793; e=2.718281828459045; printf "%.15f", ('"${expression}"'); print ""; }'

# Example 1:
# ./scicalc '(sin(pi / 3.5) * sin(pi / 3.5) + cos(pi / 3.5) * cos(pi / 3.5)) / 3.0'
# Result:
# 0.333333333333333
# Google result:
# 0.33333333333
#
# Example 2:
# ./scicalc '(123.456**(1.2/3.4))'
# Result:
# 5.472437081627787
# Google result:
# 5.47243708163

Results on both this MBP and the AMIGA, not tested in Linux flavours:

Last login: Sun Jul 14 19:08:41 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> ./scicalc '(sin(pi / 3.5) * sin(pi / 3.5) + cos(pi / 3.5) * cos(pi / 3.5)) / 3.0'
0.333333333333333
AMIGA:amiga~/Desktop/Code/Shell> ./scicalc '123.456**(1.2/3.4)'
5.472437081627787
AMIGA:amiga~/Desktop/Code/Shell> NUM='123.456**(1.2/3.4)'
AMIGA:amiga~/Desktop/Code/Shell> ./scicalc "$NUM"
5.472437081627787
AMIGA:amiga~/Desktop/Code/Shell> ./scicalc "$NUM" > /tmp/text
AMIGA:amiga~/Desktop/Code/Shell> cat /tmp/text
5.472437081627787
AMIGA:amiga~/Desktop/Code/Shell> ./scicalc
Basic USAGE: [./]scicalc [']["]expression_inside_quotes["][']<CR>
!!!Read the code for more information!!!
AMIGA:amiga~/Desktop/Code/Shell> echo "$?"
1
AMIGA:amiga~/Desktop/Code/Shell> _

I think this is good enough for the average user...

2 Likes

Now tested inside a current Linux Mint 19.

Awk Version:
GNU Awk 4.1.4, API: 1.1 (GNU MPFR 4.0.1, GNU MP 6.1.2)
Copyright (C) 1989, 1991-2016 Free Software Foundation.

The POSIX shell 'sh' links to dash:
Version 0.5.8-2.10 500
Using from the Linux terminal:
Prompt:-$ apt-cache policy dash<CR>

A very practical use of scicalc and this will be the last upload...
I am creating an audio function generator and wanted to use ASCII only for all of the waveforms so that a simple arbitrary waveform could be created using a text editor, and all other waveforms can be edited too.
Well this is not fast but generates a sinewave in pure ASCII only. It is a practical use of 'scicalc'.

#!/bin/sh

# #!/usr/local/bin/dash
# text_sinewaves.sh

WAVEFORM=""

# 64 bytes per cycle:
# for ANGLE in $( seq 0.0 5.625 359.0 )
# 8 bytes per cycle:
for ANGLE in $( seq 0.0 45.0 359.0 )
do
    FLOAT=$( ~/Desktop/Code/Shell/scicalc "(((sin((${ANGLE}*pi)/180)+1)/2.0)*94)+32" )
    # Don't use awk's """int()""" function as it rounds down only, use """printf "%.0f" ...""" instead.
    WAVEFORM=${WAVEFORM}$( printf \\$( printf "%03o" $( printf "%.0f" "${FLOAT}" ) ) )
done
echo "${WAVEFORM}"
echo "Length = ${#WAVEFORM} bytes."

Results; editing for both for loops:

Last login: Mon Jul 22 16:18:46 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> ./text_sinewaves.sh
OTX]aeimpsvxz|}~~~}|zxvspmiea]XTOJFA=951.+(&$"!   !"$&(+.159=AFJ
Length = 64 bytes.
AMIGA:amiga~/Desktop/Code/Shell> ./text_sinewaves.sh
Op~pO. .
Length = 8 bytes.
AMIGA:amiga~/Desktop/Code/Shell> _

How does it work:
First things first, there are 95 normal printable ASCII characters from ASCII 32 decimal " ", and ASCII 126 decimal "~".
The _centreline_ character is ASCII 79 decimal "O", (not ZERO but capital O).
So we have three conditions to take care of, the minimum value must be no less than ASCII 32 " ", the centreline pseudo-DC ASCII 79 "O", (Direct Current level), and finally the maximum value must be no more ASCII 126 "~".

Now consider the expression "(((sin((${ANGLE}*pi)/180)+1)/2.0)*94)+32" ...
There is no need for any start and end parentheses as this is catered for inside 'scicalc'; it does not matter if you add them though.
As 'sin(x)' from 0 to 360 degrees goes from 0 to +1 to 0 to -1 and finally back to 0 again we have to remove the negative part so +1 is added to every calculated result.
This now moves the values to 1 to 2 to 1 to 0 and finally back to 1 again.
When that is done those values are divided by 2 to give the range 0.5 to 1 to 0.5 to 0 and finally back to 0.5.
0.5 is now the centreline, or DC, and this is now multiplied by the (number_of_printable_characters - 1).
We are not done yet; as this will go from 0.0 to 94.0 then the whole has to be shifted up so 0.0 becomes 32.0 and 94.0 becomes 126.0 so 32 must be finally added, and voila, using the script 8 or 64 byte ASCII single cycle pseudo-sinewave is created.
I hope this is lucid enough.
Note that 'printf "%.0f" ' is used to create the integer values, see the code...
(And also doing this manually would take ages.)
Enjoy...

Bazza.