int vs float divide: abbreviating numbers w/SI units

David Eppstein eppstein at ics.uci.edu
Sun Jul 29 13:55:58 EDT 2001


In article <3b63a8ec.700705120 at wa.news.verio.net>,
 bokr at accessone.com (Bengt Richter) wrote:

> I was going to make a one-liner, but it would be really ugly and repeat stuff 
> ;-)
> But there might be something in this you can use?:
> 
> import math
> def abbrn(n,k=1000):
>     if n==0: return '0'
>     nk, rk = divmod(math.log(abs(n)), math.log(k))
>     nkr = max(-9, min(int(nk), 9))
>     suffix= 'kyzafpnum kMGTPEZYk'[nkr+9] + (abs(nkr)==9)*("^%d" % (nk,) )
>     sr = ("%1.1f" % (math.exp(rk),))
>     adjlen = len(sr) - 2*(sr[-1]=='0' or len(sr)>3)
>     return '-'*(n<0) + sr[0:adjlen] + suffix
> 
> I think it does what yours does, except I rely on %1.1f to round and
> just chuck the '.0' or .x if there's more than 3 chars, which makes
> some differences, e.g.,
> 
> for the args 2.0*10.**-30 1000
> yours => 2.0k^-10
> mine  => 2k^-10

Thanks for the suggestions.

Unfortunately, there are cases where counting three chars is the wrong 
thing to do.  E.g. in my code, abbreviateNumber(1012,k=1024) returns '1012'.
Also I'm worried that the approximations involved in the math.log and 
math.exp would prevent the algorithm from noticing that some values are 
equal to integers, e.g. my code abbreviateNumber(1000) returns '1k' rather 
than '1.0k'.
-- 
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