A fixed point basic calculator for DASH.

Tags
basic, calculator, dash, point

Login to Reply

 
Thread Tools Search this Thread
# 15  
Old 3 Weeks Ago
Here is the fixed point arithmetic code for a fixed point basic calculator for DASH... Cheers.

Code:
#!/bin/bash
# Fixed point arithmetic
DP=3 # Decimal Places
MOD=1000 # 1 * 10^DP

function ftofix {       # ftofix OUTPUTNAME "3.14"
        _VAR="$1"
        _OLDIFS="$IFS"
        IFS="."
                set -- $2 # Set $1, $2, etc, splitting on "."
        IFS="$_OLDIFS"
        local FRAC=$2
        local _N=$1

        [[ "${_N}" =  "0" ]] && _N=""
        [[ "${_N}" = "-0" ]] && _N="-"

        for((X=0; X<DP; X++))
        do
                D="${FRAC:$X:1}"
                [[ -z "$D" ]] && D="0"
                _N="${_N}$D" # Prepend digits to N
        done
        read $_VAR <<EOF
${_N}
EOF

}

function fixtof {
        _VAR="$1"
        _N="$2"
        _SIGN=""
        ((_N<0)) && _SIGN="-" && ((_N=-_N))
        _S=`printf "%d.%0${DP}d" $((_N/MOD)) $((_N%MOD))`
        read $_VAR <<EOF
$_S
EOF
}

AA="3.14159"
BB="2.0"

ftofix A $AA
ftofix B $BB

# Multiplcation
fixtof CC $(((A*B)/MOD))
echo "$AA * $BB = $CC"

# Division
fixtof DD $(( (A*MOD)/B ))
echo "$AA / $BB = $DD"

# Addition and Subtraction
fixtof EE $(( B - A ))
echo "$BB - $AA = $EE"
fixtof FF $(( A - B ))
echo "$AA - $BB = $FF"
fixtof GG $(( A + B ))
echo "$AA + $BB = $GG"


Last edited by Corona688; 3 Weeks Ago at 05:31 PM..
# 16  
Old 3 Weeks Ago
Apologies for the delay, I am a carer or babysitter presently for my mother or grandchild and dogs.
However @ Corona688...

Well tested your 'BASH' version with just one edge case and there will be quite a few...
Note with your original, 2.0 - 3.14159 = -1.141, not what is shown.
Then I just did one edge case, I changed '2.0' to '0.073' and...
NOTE: Not related to either your or my versions; I have manually found many edgecases. Python was a godsend for this task.
Code:
Last login: Fri Nov 23 21:29:04 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> ./FPMATH_C688.sh
3.14159 * 2.0 = 6.282
3.14159 / 2.0 = 1.570
2.0 - 3.14159 = 1.141		# WRONG! -1.141
3.14159 - 2.0 = 1.141
3.14159 + 2.0 = 5.141
AMIGA:amiga~/Desktop/Code/Shell> # Just one edge case, change BB to 0.073.
AMIGA:amiga~/Desktop/Code/Shell> ./FPMATH_C688.sh
3.14159 * 0.073 = 0.185
3.14159 / 0.073 = 53.237
0.073 - 3.14159 = 3.082
3.14159 - 0.073 = 3.082
3.14159 + 0.073 = 3.200
AMIGA:amiga~/Desktop/Code/Shell> # Oops, they are all wrong.
AMIGA:amiga~/Desktop/Code/Shell> _

Code:
Google calculator:
3.14159 * 0.073 = 0.229
3.14159 / 0.073 = 43.035
0.073 - 3.14159 = -3.068
3.14159 - 0.073 = 3.068
3.14159 + 0.073 = 3.214

As I said I have learnt a lot about 'dash' and POSIX. Your 'heredoc' code is wonderful.
As above I have found many edge cases.
Also the strange effects closing the gaps to the + or - limits I have set.
I will be back ASAP but family comes first.

Last edited by wisecracker; 3 Weeks Ago at 05:37 AM.. Reason: Correct grammar.
# 17  
Old 5 Days Ago
There was a bug in my version above. Arithmetic involving negative numbers worked, the edge case was the display of them. One 'edge' was that I completely forgot to display the sign, at all, ever. Still trying to fix the 0.073 problem.

Code:
DP=3
MOD=1000

function ftofix {       # ftofix OUTPUTNAME "3.14"
        _VAR="$1"
        _OLDIFS="$IFS"
        IFS="."
                set -- $2 # Set $1, $2, etc, splitting on "."
        IFS="$_OLDIFS"
        local FRAC=$2
        local _N=$1

        [[ "${_N}" =  "0" ]] && _N=""
        [[ "${_N}" = "-0" ]] && _N="-"

        for((X=0; X<DP; X++))
        do
                D="${FRAC:$X:1}"
                [[ -z "$D" ]] && D="0"
                _N="${_N}$D" # Prepend digits to N
        done
        read $_VAR <<EOF
${_N}
EOF

}

function fixtof {
        _VAR="$1"
        _N="$2"
        _SIGN=""
        ((_N<0)) && _SIGN="-" && ((_N=-_N))
        _S=`printf "%s%d.%0${DP}d" "${_SIGN}" $((_N/MOD)) $((_N%MOD))`
        read $_VAR <<EOF
$_S
EOF
}

AA="3.14159"
BB="-2.0"

ftofix A $AA
ftofix B $BB

# Multiplcation
fixtof CC $(((A*B)/MOD))
echo "$AA * $BB = $CC"

# Division
fixtof DD $(( (A*MOD)/B ))
echo "$AA / $BB = $DD"

# Addition and Subtraction
fixtof EE $(( B - A ))
echo "$BB - $AA = $EE"
fixtof FF $(( A - B ))
echo "$AA - $BB = $FF"
fixtof GG $(( A + B ))
echo "$AA + $BB = $GG"

Code:
3.14159 * -2.0 = -6.282
3.14159 / -2.0 = -1.570
-2.0 - 3.14159 = -5.141
3.14159 - -2.0 = 5.141
3.14159 + -2.0 = 1.141

# 18  
Old 5 Days Ago
I wonder why in a thread with title "DASH" you use function, a keyword that is not known in dash. dash needs
Code:
funcname(){ ... }

# 19  
Old 5 Days Ago
Code:
DP=3
MOD=1000

function ftofix {       # ftofix OUTPUTNAME "3.14"
        local _N="0"
        local D=0
        local X
        local Y

        # Convert "VAR" "-.3" into "VAR" "-" "0.3", etc
        case "$2" in
        [.]*)           set -- "$1" "" "0$2"            ;;
        [0-9]*)         set -- "$1" "" "$2"             ;;
        [+-][0-9.]*)    set -- "$1" "${2:0:1}" "${2:1}" ;;
        *)              return 1                        ;;
        esac

        for((X=0; X<${#3}; X++))
        do
                if [[ "${3:$X:1}" == "." ]]
                then
                        (( X++ )) ; break
                fi

                (( _N = (10*_N) + ${3:$X:1} ))
        done

        while [[ "$D" -lt "$DP" ]]
        do
                Y="${3:$((X+D)):1}"
                [ -z "$Y" ] && Y=0

                (( _N = (10*_N) + Y ))
                (( D++ ))
        done

        read "$1" <<EOF
${2}${_N}
EOF
}

function fixtof {
        _VAR="$1"
        _N="$2"
        _SIGN=""
        ((_N<0)) && _SIGN="-" && ((_N=-_N))
        _S=`printf "%s%d.%0${DP}d" "${_SIGN}" $((_N/MOD)) $((_N%MOD))`
        read $_VAR <<EOF
$_S
EOF
}

AA="3.14159"
BB="-0.073"

ftofix B $BB
ftofix A $AA

# Multiplcation
fixtof CC $(((A*B)/MOD))
echo "$AA * $BB = $CC"

# Division
fixtof DD $(( (A*MOD)/B ))
echo "$AA / $BB = $DD"

# Addition and Subtraction
fixtof EE $(( B - A ))
echo "$BB - $AA = $EE"
fixtof FF $(( A - B ))
echo "$AA - $BB = $FF"
fixtof GG $(( A + B ))
echo "$AA + $BB = $GG"

Code:
3.14159 * -0.073 = -0.229
3.14159 / -0.073 = -43.027
-0.073 - 3.14159 = -3.214
3.14159 - -0.073 = 3.214
3.14159 + -0.073 = 3.068


Last edited by Corona688; 5 Days Ago at 03:38 PM..
# 20  
Old 4 Days Ago
BASH mandelbrot set:

Code:
DP=8
MOD=1
while [[ "${#MOD}" -le "${DP}" ]]
do
        MOD="${MOD}0"
done

ESCAPED=0

function ftofix {       # ftofix OUTPUTNAME "3.14"
        local _N="0"
        local D=0
        local X
        local Y

        # Convert "VAR" "-.3" into "VAR" "-" "0.3", etc
        case "$2" in
        [.]*)           set -- "$1" "" "0$2"            ;;
        [0-9]*)         set -- "$1" "" "$2"             ;;
        [+-][0-9.]*)    set -- "$1" "${2:0:1}" "${2:1}" ;;
        *)              return 1                        ;;
        esac

        for((X=0; X<${#3}; X++))
        do
                if [[ "${3:$X:1}" == "." ]]
                then
                        (( X++ )) ; break
                fi

                (( _N = (10*_N) + ${3:$X:1} ))
        done

        while [[ "$D" -lt "$DP" ]]
        do
                Y="${3:$((X+D)):1}"
                [ -z "$Y" ] && Y=0

                (( _N = (10*_N) + Y ))
                (( D++ ))
        done

        read "$1" <<EOF
${2}${_N}
EOF
}

function fixtof {
        _VAR="$1"
        _N="$2"
        _SIGN=""
        ((_N<0)) && _SIGN="-" && ((_N=-_N))
        _S=`printf "%s%d.%0${DP}d" "${_SIGN}" $((_N/MOD)) $((_N%MOD))`
        read $_VAR <<EOF
$_S
EOF
}

function escape { # R I
        # Z Z C C R
        set -- 0 0 $1 $2 $(( (($1*$1)+($2*$2))/MOD ))
        local N=0

        while [[ "$N" -lt "$EMAX" ]] && [[ "$5" -lt $((4*MOD)) ]]
        do
                set -- $(( $3 + (($1*$1) - ($2*$2))/MOD ))      \
                        $(( $4 + (2*$1*$2)/MOD )) $3 $4         \
                        $(( (($1*$1)+($2*$2))/MOD ))
                (( N++ ))
        done

        (( N >= EMAX )) && (( ESCAPED ++ ))

        return $N
}

Y=0

STUFF=" .oOo. -=%#%=-"

ftofix CY       ${1-0.0}
ftofix CX       ${2--0.5}
ftofix W        ${3-1.0}
EMAX=${4-100}

XMIN=$((CX-W))
XMAX=$((CX+W))
YMIN=$((CY-W))
YMAX=$((CY+W))

XSTEP=$(( (XMAX-XMIN) / 70 ))
YSTEP=$(( (YMAX-YMIN) / 20 ))

for ((Y=YMIN; Y < YMAX; Y += YSTEP ))
do
        S=""
        for ((X=XMIN; X < XMAX; X += XSTEP ))
        do
                escape "$X" "$Y"
                Z="$?"
                [ "$Z" -eq "$EMAX" ] && Z=0 || (( Z %= ${#STUFF} ))

                S="$S${STUFF:$Z:1}"
        done
        echo "|$S|"
done

echo "Escaped $ESCAPED times" >&2

exit 0

Code:
./mandel2.sh

|Ooooooooooooooooooooooooooooo...........    -=%%.#%=-- ........oooooooO|
|oooooooooooooooooooooooo.............     -=%#%o%%o%%=-    .......ooooo|
|oooooooooooooooooooo.............   ----==%%O      .# #=--      .....oo|
|oooooooooooooooo...........   -==%o%%%%%##%=.       O=%##%==----==- ...|
|oooooooooooo......        ---==% .  Ooo                   o-=-=oo%==  .|
|oooooo....             ----=%# =.                               = %--  |
|....  -=%%%==============%%#=.o                                  .%#== |
|     --=%% o-o-- %   =%##%%.%                                     o-%--|
|   -===%-=.=            -oO%                                      -.#- |
|==%%- O.o                 O                                       %=-  |
|                                                              --%%=--  |
|==%%- O.o                 O                                       %=-  |
|   -===%-=.=            -oO%                                      -.#- |
|     --=%% o-o-- %   =%##%%.%                                     o-%--|
|....  -=%%%==============%%#=.o                                  .%#== |
|oooooo....             ----=%# =.                               = %--  |
|oooooooooooo......        ---==% .  Ooo                   o-=-=oo%==  .|
|oooooooooooooooo...........   -==%o%%%%%##%=.       O=%##%==----==- ...|
|oooooooooooooooooooo.............   ----==%%O      .# #=--      .....oo|
|oooooooooooooooooooooooo.............     -=%#%o%%o%%=-    .......ooooo|

$

I don't expect this to run on the amiga with any reasonable speed.
This User Gave Thanks to Corona688 For This Post:
wisecracker (4 Days Ago)
# 21  
Old 4 Days Ago
Hi Corona688...

This edge case works on my version...
I have limited my decimal point to 9 decimal places BUT note the non-zero digits start at the 10th decimal place:
Code:
Last login: Wed Dec 12 06:48:08 on console
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> ./calc .000000000123 + .0000000007
+0.000000001
AMIGA:amiga~/Desktop/Code/Shell> ./calc .000000000923 + .000000000739
+0.000000002
AMIGA:amiga~/Desktop/Code/Shell> ./calc .000000000123 + .000000000123
+0.000000000
AMIGA:amiga~/Desktop/Code/Shell> _

I have certainly discovered that it is more difficult than I expected. There is at least one division edge case that is not straightforwards.
As I stated before python 2.x or 3.x was my friend here...
But yours in 'bash' gives...
I have changed 'AA' and 'BB' to:
Code:
AA=0.000945
BB=0.000789

There are other edge cases.
Ignoring the divide case as that is an edge case in itself and is different from the one mentioned above.
Code:
Last login: Wed Dec 12 13:02:10 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> ./FPMATH_C688.sh
0.000945 * 0.000789 = 0.000
./FPMATH_C688.sh: line 54: (A*MOD)/B : division by 0 (error token is " ")
0.000945 / 0.000789 = 
0.000789 - 0.000945 = 0.000
0.000945 - 0.000789 = 0.000
0.000945 + 0.000789 = 0.000
AMIGA:amiga~/Desktop/Code/Shell> _

This is getting more difficult by the version.

--- Post updated at 01:28 PM ---

Hi C688...
Your mandlebrot probably won't work on the AMIGA, period, as there is no bash for it, only ksh88.
Nevertheless it looks cool.
Off to try it out on this machine...
OSX 10.14.1, default bash terminal.
I'll be back to let you know...

Last edited by wisecracker; 4 Days Ago at 09:59 AM.. Reason: Move one text line further down.
Login to Reply

|
Thread Tools Search this Thread
Search this Thread:
Advanced Search

Similar Threads More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Fixed mount point for a USB cardreader (Raspberry Pi, UDEV) Eomer Shell Programming and Scripting 0 04-17-2016 01:15 PM
How to sum up data in fixed width file with decimal point? patricjemmy6 Post Here to Contact Site Administrators and Moderators 1 02-24-2015 07:51 PM
Exclude dash in grep Subbeh Shell Programming and Scripting 3 01-21-2013 06:58 AM
How to perform a hexdump using dd from start point to end point? jao_madn Shell Programming and Scripting 3 04-08-2012 04:32 AM
email address starting with dash akaq AIX 1 06-26-2009 05:52 AM
remove dash melanie_pfefer Shell Programming and Scripting 1 01-26-2009 06:05 AM
ignoring a dash in file name LumpSum UNIX for Dummies Questions & Answers 5 08-04-2008 01:47 PM
dash after ampersant csecnarf UNIX for Dummies Questions & Answers 2 03-12-2008 04:47 PM
double-dash options dhinge Shell Programming and Scripting 1 01-10-2007 10:32 PM
Fibre connection Point to Point SUN kie UNIX for Advanced & Expert Users 6 05-20-2003 12:20 PM
All times are GMT -4. The time now is 01:30 PM.

Unix & Linux Forums Content Copyright 1993-2018. All Rights Reserved.