name_units ()
{
	local n=$1 s
	if [ "$USE_BINARY_UNITS" ]
	then
		case $n in
		0) s=B ;;
		1) s=KiB ;;
		2) s=MiB ;;
		3) s=GiB ;;
		4) s=TiB ;;
		5) s=PiB ;;
		esac
	else
		case $n in
		0) s=B ;;
		1) s=kB ;;
		2) s=MB ;;
		3) s=GB ;;
		4) s=TB ;;
		5) s=PB ;;
		esac
	fi
	echo $s
}

disk_units ()
{
	local n=$1 r
	if [ "$USE_BINARY_UNITS" ]
	then
		case $n in   # (2^10)^{0,1,2,3,4,5}
		0) r=1 ;;
		1) r=1024 ;;
		2) r=1048576 ;;
		3) r=1073741824 ;;
		4) r=1099511627776 ;;
		5) r=1125899906842624 ;;
		esac
	else
		case $n in   # (10^3)^{0,1,2,3,4,5}
		0) r=1 ;;
		1) r=1000 ;;
		2) r=1000000 ;;
		3) r=1000000000 ;;
		4) r=1000000000000 ;;
		5) r=1000000000000000 ;;
		esac
	fi
	echo $r
}

longint2human () {
	local longint radix bytes int frac deci exp
	# fallback value for $deci:
	deci="${deci:-.}"
	bytes=$1
	exp=6   # possible units
	while [ $exp -gt 0 ]
	do
		exp=$((exp-1))
		radix=$(disk_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 -gt 0 ]
	then
		printf "%i%s%02i %s\n" $int $deci $frac $(name_units $exp)
	else
		printf "%i %s\n" $int $(name_units $exp)
	fi
}

human2longint () {
	local human orighuman gotb suffix int frac longint 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|p|P)
		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 ;;
	p|P)
		exp=5 ;;
	esac
	expr $longint \* $(disk_units $exp) / 10000
}
