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