mirror of
https://dicksdeathabove.xyz/~mia/psh-fractional
synced 2024-11-09 01:44:28 +00:00
finish long subtraction
This commit is contained in:
parent
c5a5c00d83
commit
04d7b5e20f
119
subtraction/sub
Normal file → Executable file
119
subtraction/sub
Normal file → Executable file
|
@ -0,0 +1,119 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# long subtraction !?
|
||||||
|
# $f1 - $f2
|
||||||
|
countd() { # count decimal places
|
||||||
|
m="$1"; n=${2:-0}; while [ "$m" ]; do
|
||||||
|
: $((n+=1))
|
||||||
|
next="${m%?}"
|
||||||
|
[ "${m#$next}" = "." ] && {
|
||||||
|
break
|
||||||
|
} || {
|
||||||
|
m="$next"
|
||||||
|
}
|
||||||
|
done
|
||||||
|
echo "$n"
|
||||||
|
}
|
||||||
|
borrow(){
|
||||||
|
# $2 current number (to increase)
|
||||||
|
# $1 as whole number; will return modified
|
||||||
|
# $3 as $next
|
||||||
|
b="${1%$2}"; b="${b#${3%?}}"
|
||||||
|
[ "$b" -gt 0 ] && {
|
||||||
|
c1="$2";
|
||||||
|
[ "$b" -eq 10 ] && {
|
||||||
|
o="${1%$b$2}"; : $((b-=1)); o="${o}0${b}$c1" # eg 21 = 2090 10
|
||||||
|
# tbh idk why this works; 2090 should acctually be 1 10 9 10
|
||||||
|
# which somehow becomes 209 10 ? I'm guessing a second borrow call is made
|
||||||
|
# and that somehow corrects it; but again idk; a second borrow call /is/ made
|
||||||
|
# but idk how it corrects it
|
||||||
|
} || {
|
||||||
|
o="${1%$b$2}"; : $((b-=1)); o="$o$b$c1"
|
||||||
|
}
|
||||||
|
: $((c1+=10))
|
||||||
|
echo "$o $c1"
|
||||||
|
} || { # otherwise use recusion
|
||||||
|
o="${1#${3%?}}"; o="${o%$2}"
|
||||||
|
borrow "$1" "$o" "${3%?}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[ -z "${1##*.*}" -o -z "${2##*.*}" ] && {
|
||||||
|
|
||||||
|
if [ ! -z "${1##*.*}" ]; then # if $1 is not float
|
||||||
|
zp1="$1"; zp2="${2%.*}${2#*.}"
|
||||||
|
elif [ ! -z "${2##*.*}" ]; then
|
||||||
|
zp1="${1%.*}${1#*.}"; zp2="$2"
|
||||||
|
else
|
||||||
|
zp1="${1%.*}${1#*.}"; zp2="${2%.*}${2#*.}"
|
||||||
|
fi # yank out decimal places to compare
|
||||||
|
if [ "${#zp1}" -gt "${#zp2}" ]; then
|
||||||
|
until [ "${#zp2}" -eq "${#zp1}" ]; do
|
||||||
|
zp2="${zp2}0"
|
||||||
|
done
|
||||||
|
elif [ "${#zp1}" -lt "${#zp2}" ]; then
|
||||||
|
until [ "${#zp1}" -eq "${#zp2}" ]; do
|
||||||
|
zp1="${zp1}0"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
[ "$zp2" -gt "$zp1" ] && {
|
||||||
|
set -- "$2" "$1"
|
||||||
|
nr=-
|
||||||
|
}
|
||||||
|
# above handles negative results
|
||||||
|
|
||||||
|
# determine decimal point
|
||||||
|
if [ "${#1}" -gt "${#2}" -a -z "${1##*.*}" ]; then # if $1 has no decimal points it should not be counted
|
||||||
|
# this fixes a but when $1 is longer than $2 but has no decimal points
|
||||||
|
dn=$(countd "$1")
|
||||||
|
elif [ "${#1}" -lt "${#2}" -a -z "${2##*.*}" ]; then # same here
|
||||||
|
dn=$(countd "$2")
|
||||||
|
else # equal
|
||||||
|
dn=$(countd "$2")
|
||||||
|
fi
|
||||||
|
zp1="${1%%.*}"; zp2="${2%%.*}"
|
||||||
|
[ "${#zp1}" -gt "${#zp2}" ] && until [ "${#zp1}" -eq "${#zp2}" ]; do
|
||||||
|
set -- "$1" "0$2"
|
||||||
|
zp1="${1%%.*}"; zp2="${2%%.*}"
|
||||||
|
done
|
||||||
|
[ "${#zp1}" -lt "${#zp2}" ] && until [ "${#zp1}" -eq "${#zp2}" ]; do
|
||||||
|
set -- "0$1" "$2"
|
||||||
|
zp1="${1%%.*}"; zp2="${2%%.*}"
|
||||||
|
done; unset zp1 zp2
|
||||||
|
[ "$dn" -gt 0 ] && : $((dn-=1))
|
||||||
|
if [ ! -z "${1##*.*}" ]; then # if $1 not float
|
||||||
|
set -- "${1}.0" "$2"
|
||||||
|
elif [ ! -z "${2##*.*}" ]; then
|
||||||
|
set -- "$1" "${2}.0"
|
||||||
|
fi
|
||||||
|
#echo "$1 $2"
|
||||||
|
set -- "${1%.*}${1#*.}" "${2%.*}${2#*.}" # remove decimals
|
||||||
|
f1="$1"; f2="$2"
|
||||||
|
[ "${#f1}" -lt "${#f2}" ] && until [ "${#f1}" -eq "${#f2}" ]; do
|
||||||
|
f1="${f1}0"
|
||||||
|
done
|
||||||
|
[ "${#f1}" -gt "${#f2}" ] && until [ "${#f2}" -eq "${#f1}" ]; do
|
||||||
|
f2="${f2}0"
|
||||||
|
done # 0 padding
|
||||||
|
#echo "$f1 - $f2"
|
||||||
|
while [ "$f1" ]; do
|
||||||
|
while [ "$f2" ]; do # shift over both numbers; double while
|
||||||
|
next1="${f1%?}"; next2="${f2%?}"; c1="${f1#$next1}"; c2="${f2#$next2}"
|
||||||
|
[ "$c1" -lt "$c2" ] && { # regroup
|
||||||
|
b=$(borrow "$f1" "$c1" "$next1")
|
||||||
|
c1="${b#* }"; f1="${b% *}"; next1="${f1%?}"
|
||||||
|
#echo "-- $f1 / $b"
|
||||||
|
}
|
||||||
|
#echo "$c1 - $c2 | $f1 - $f2"
|
||||||
|
o="$((c1-c2))$o" # subtract
|
||||||
|
f1="$next1"; f2="$next2"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
[ "$dn" -gt 0 ] && {
|
||||||
|
n=0; f1="$o"; while [ "$f1" ]; do
|
||||||
|
next="${f1%?}"
|
||||||
|
: $((n+=1))
|
||||||
|
[ "$n" -eq "$dn" ] && o="$next.${o#${f1%?}}"
|
||||||
|
f1="$next"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
echo "${nr}$o" # $nr is for negative handling
|
||||||
|
} || echo $(($1-$2)) # NOT float
|
Loading…
Reference in a new issue