# Strange rounding problem

Dan Bishop danb_83 at yahoo.com
Sun Mar 16 10:38:40 CET 2003

```Steven Taschuk <staschuk at telusplanet.net> wrote in message news:<mailman.1047756866.24097.python-list at python.org>...
> Quoth Jp Calderone:
>   [...]
> >   I believe the rule is generally expressable - a base can exactly represent
> > fractions which can be expressed as sums of the inverses of powers of
> > factors of the base.  [...]
>
> ... and only those fractions.
>
> The proof is not difficult.  A value x with a terminating
> expression
> 	x = 0 . a_1 a_2 a_3 ... a_n
> in some base b obviously has the property that
> 	x * b^n is an integer
> and conversely, any value x with this property has a terminating
> expression.  So a fraction p/q has a terminating expression if and
> only if q divides some power of b, that is, if and only if all of
> q's prime factors are also prime factors of b.  Your description
> of the rule follows quickly.
>
>   [...]
> >   15 is the next best base after 10, and 30 after that.  Of course, no base
> > can exactly represent any fraction, and this doesn't even take into
> > consideration bases which are, themselves, fractional ;)
>
> 6 and 14 seem just as good as 10 and 15 to me, by this criterion.

Imho, 6 would be better than either 10 or 14, because for any
sufficiently large finite range of integers, there are more multiples
of 3 than multiples of 5 and 7.

If we define the utility of a number base as proportional to the
number of its factors (excluding itself), and inversely proportional
to the magnitude of those factors (and use the Python script at the
end of this message to calculate those factors), we find that the best
bases are 12 (1.562), 6 (1.500), and 24 (1.361), and that bases 14,
21, 22, 25-28, and 32-35 are worse than the prime bases.

------------------------------------------------------------------------

#!/usr/bin/env python

from __future__ import division
import operator

def factors(n):
# list of factors of n, including 1 and excluding n
return [i for i in xrange(1, n // 2 + 1) if not n % i]

def mean(seq):

def utility(base):
# an arbitrary definition of how "good" a number base is
f = factors(base)
return len(f) / mean(f)

def main():
print 'base    utility'
print '----    -------'
for base in xrange(2, 37):
print ' %2d       %.3f' % (base, utility(base))

if __name__ == '__main__':
main()

```