int vs float divide: abbreviating numbers w/SI units
David Eppstein
eppstein at ics.uci.edu
Sat Jul 28 21:29:30 CEST 2001
Some time buried in the recent division flamewar I posted a message listing
the uses I'd recently made of integer division, one of which was some short
code for abbreviating numbers like 1008926 to e.g. 988k for more readable
text output of file sizes in a web photo gallery generator.
Anyway, I decided it would be a good idea to make it more general and
robust, and discovered somewhat to my surprise that float division seems to
be a better fit for the task. The new code is below if anyone wants to
critique or use it.
def abbreviateNumber(n, k=1000):
"""Convert a number into a short string for its approximate value.
SI Units are used to convert the number to a human-readable range.
For example, abbreviateNumber(3141592) returns '3.1M'.
In most cases (except when the number is too big or too small
for the units defined in the SI system) the resulting string
will be at most four characters long.
By default, the program uses decimal k (i.e. 1k = 1000).
To use binary k, as is more typical e.g. for numbers of bytes,
call with a second argument k=1024.
"""
# determine number of factors of k and normalize 0.9995 <= n < 999.5
k = float(k) # force floating-point divisions
nk = 0
sign = ''
if n < 0:
n = -n
sign = '-'
while n >= 999.5:
n /= k
nk += 1
while 0 < n < 0.9995:
n *= k
nk -= 1
try:
if nk > 0: suffix = ' kMGTPEZY'[nk]
elif nk < 0: suffix = ' munpfazy'[-nk]
else: suffix = ''
except:
suffix = 'k^%d' % nk
# decide whether to use integer or decimal form and construct result
if n < 9.95 and n != round(n):
strn = "%1.1f" % n
else:
strn = "%d" % round(n)
return sign + strn + suffix
--
David Eppstein UC Irvine Dept. of Information & Computer Science
eppstein at ics.uci.edu http://www.ics.uci.edu/~eppstein/
More information about the Python-list
mailing list