suffix_units=(B kB MB GB TB)

decimal_units=(1 1000 1000000 1000000000 1000000000000)  # (10^3)^{0,1,2,3,4}

binary_units=(1 1024 1048576 1073741824 1099511627776)   # (2^10)^{0,1,2,3,4}

longint2human () {
	local longint radix bytes int frac deci units exp
	# fallback value for $deci:
	deci="${deci:-.}"
	[ "$USE_BINARY_UNITS" ] && units=(${binary_units[*]}) \
				|| units=(${decimal_units[*]})
	bytes=$1
	exp=${#units[*]}
	while ((exp>0))
	do
		((exp-=1))
		radix=${units[exp]}
#		expr $bytes ">=" $radix >/dev/null && break
		expr 1000 \* $bytes ">=" 995 \* $radix >/dev/null && break
	done
	longint=$(expr $bytes \* 1000 + $radix \* 5)
	int=$(expr $longint / \( $radix \* 1000 \) )
	frac=$(expr $longint % \( $radix \* 1000 \) / \( $radix \* 10 \) )
	if ((exp>0))
	then
		printf "%i%s%02i %s\n" $int $deci $frac ${suffix_units[exp]}
	else
		printf "%i %s\n" $int ${suffix_units[exp]}
	fi
}

human2longint () {
	local human orighuman gotb suffix int frac longint units exp
	set -- $*; human="$1$2$3$4$5" # without the spaces
	orighuman="$human"
	human=${human%b} #remove last b
	human=${human%B} #remove last B
	gotb=''
	if [ "$human" != "$orighuman" ]; then
		gotb=1
	fi
	suffix=${human#${human%?}} # the last symbol of $human
	case $suffix in
	k|K|m|M|g|G|t|T)
		human=${human%$suffix}
		;;
	*)
		if [ "$gotb" ]; then
			suffix=B
		else
			suffix=M # default to megabytes
		fi
		;;
	esac
	int="${human%[.,]*}"
	[ "$int" ] || int=0
	frac=${human#$int}
	frac="${frac#[.,]}0000" # to be sure there are at least 4 digits
	frac=${frac%${frac#????}} # only the first 4 digits of $frac
	longint=$(expr $int \* 10000 + $frac)
	case $suffix in
	b|B)
		exp=0 ;;
	k|K)
		exp=1 ;;
	m|M)
		exp=2 ;;
	g|G)
		exp=3 ;;
	t|T)
		exp=4 ;;
	esac
	[ "$USE_BINARY_UNITS" ] && units=(${binary_units[*]}) \
				|| units=(${decimal_units[*]})
	expr $longint \* ${units[exp]} / 10000
}
