#!/bin/sh s() { n=$1; i=1; while [ "$n" -le $2 ]; do echo "$n"; : $((n+=i)) done } # seq fd() { # return first digit of $1 x="$1"; until [ "${#x}" -eq 1 ]; do x="${x%?}" done echo "$x" } ld() { # $1/$2 di="$1"; div="$2"; count="$3" case "$div" in *'.'*) sp=0; sdiv="${div%%.*}"; IFS="."; set -- ${div}; div="${1}${2}"; unset IFS sp="$((${#div}-${#sdiv}))" esac # determine where the decimal point is -- if present case "$di" in *'.'*) dp=0; t="$di"; while :; do # use while true + case/break t="${t#?}"; : $((dp+=1)) case "$t" in '.'*) break esac done ;; *) dp=0 esac [ "$dp" -gt 0 ] && { IFS="."; set -- ${di}; di="${1}${2}"; unset IFS } #echo "$sp $div ${di}/${#di}" [ "$sp" ] && { ss="${#di}"; : $((ss-=dp)); : $((ss+=sp)); : $((ss+=1)) until [ "${#div}" -eq "$ss" ]; do div="${div}0" done } #echo "-" o="$((di/div))"; dp="${#o}" [ "${#o}" -eq 0 ] && : $((count+=2)) : $((count+=${#o})) until [ "${#di}" -eq "$count" ]; do di="${di}0" done set -- "$1" "$2" "${3:-9}" "$di" "$sd" unset IFS o; n=0; for i in $(s 1 $count); do fd="$(fd $di)" # fd is needed later #echo "$fd"; [ "$i" -gt 1 ] && { fd="${sd}${fd}" #echo "$fd" } sd="$((fd/div))"; [ "$sd" -eq 0 ] && : $((count+=1)) o="${o}${sd}"; sd="$((sd*div))" #printf " %s\n- %s\n" "$fd" "$sd" sd="$((fd-sd))" #echo "| $sd" [ "$sd" -eq 0 ] && { n=0 break } # now pull down # redefine $di di="${di#?}" # $fd$sd : $((n+=1)) done [ "$n" -gt 0 ] && { count=$((count+n)) } || count=0 #echo "$fd $di/$4 - $div / $dp -- $sp | $count" # do again if $((count-n)) is > 0 [ "$count" -gt 0 ] && { di="$4"; sd="$5"; o=""; until [ "${#di}" -eq "$count" ]; do di="${di}0" done for i in $(s 1 $count); do fd="$(fd $di)" # fd is needed later [ "$i" -gt 1 ] && fd="${sd}${fd}" sd="$((fd/div))"; o="${o}${sd}"; sd="$((sd*div))"; sd="$((fd-sd))" [ "$sd" -eq 0 ] && break di="${di#?}" done } until [ "${o#0}" = "$o" ]; do o="${o#0}" done [ "$dp" -gt 0 -a "$fd" -ne "$1" ] && { [ "$t" ] || : $((dp+=1)) [ "$t" ] && : $((dp-=1)) [ "$sp" ] && : $((dp+=1)) [ "${sp:-0}" -gt 1 ] && : $((dp+=1)) #echo "$o $dp/$sp | ${#o}" do="$o"; [ "${#do}" -gt "$dp" ] && until [ "${#do}" -eq "$dp" ]; do do="${do%?}" done [ "$1" -lt "$2" ] && do="${do%?}" o="${do:-0}.${o#$do}" } [ "$1" -lt "$2" ] || until [ "${o#0}" = "$o" ]; do o="${o#0}" done echo "$o" # | $dp | $do" } # 9 decimal points unless $3 is passed [ "$1" -a "$2" ] && ld "$1" "$2" "${3:-9}"