Python code to express a large integer in words?

Bengt Richter bokr at accessone.com
Wed Aug 1 17:35:46 EDT 2001


On Tue, 31 Jul 2001 18:41:35 +0100, ptah <ptah at mjs400.co.uk> wrote:

>For interest I have included code below from the as400network Club Tech
>iSeries Programming Tips - 06.21.01 it is written in IBM RPG IV and is a
>kind of DLL (we call them service programs) that does the above, I would
>like to see how much more succinct a Python equivalent could be, purely
>because I would like to jump ship and code in something more expressive
>and need to put the case for Python to people who are not in the habit
>of thinking in an abstract way ;)
>
This stuff exists, but I did this to look similar to the logic of your
program, although I chose to collapse the table of 100 names a little
and not use a text string to test for hundreds etc. If you add names
to the Grps list (that's all ;-) you should get extended naming
capability for bigger numbers. It should tell you to do that if needed.
Does that make it a self-modifying program? ;-)

Bear in mind that inputs in floating format only have about 15 digits
of accuracy, but you can enter longs. Exact powers of ten can go
to 1e22 accurately because of the trailing binary 0's:
 >>> long(1e22)
 10000000000000000000000L
 >>> long(1e23)
 99999999999999991611392L
so that's an easy way to type tests for the group names.
If you want a 1.5.2 version, you'll have to change += to append
and do int() on longs used as subscripts, and change ''.join()

____________________________________________________________
#!/usr/bin/python
# engnum.py prints number names
# just add names to Grps list to extend naming capability
# Runs on Python 2.1 but has syntax beyond 1.5.2

Words = [
    'fnord','one','two','three','four',     # (fnord is place holder)
    'five','six','seven','eight','nine',
    'ten','eleven','twelve','thirteen','fourteen',
    'fifteen','sixteen','seventeen','eighteen','nineteen']

Words10 = [
    'fnord','fnord','twenty','thirty','forty',
    'fifty','sixty','seventy','eighty','ninety']

Grps = ['','thousand','million','billion','trillion']

MaxGrps = len(Grps)

def CvtNbrToWords( Nbr ):
    if Nbr == 0: return 'zero'
    num = long(Nbr)
    if num != Nbr:
        raise ArithmeticError,"Integral value required."
    if abs(num)>= 1000L**MaxGrps:
        raise ArithmeticError, \
            "To see, add name(s) after %s in Grps list of %s." % (Grps[-1], sys.argv[0])
    if num < 0:
        RtnWords = ['negative']
        num = -num
    else:
        RtnWords = []
    
    for grp in xrange(MaxGrps):
        grpFactor, num = divmod( num, 1000L**(MaxGrps-1-grp ) )
        if grpFactor:
            hundreds, tens = divmod(grpFactor, 100)
            if hundreds:
                RtnWords += [Words[hundreds],'hundred']
            if 0<tens<20:
                RtnWords.append(Words[tens])
            elif tens>0:
                tens, units = divmod( tens, 10)
                if tens and units:
                    RtnWords += [Words10[tens]+'-'+Words[units]]
                elif tens:
                    RtnWords += Words10[tens]
                elif units:
                    RtnWords += Words[units]
            RtnWords += [(Grps[MaxGrps-1-grp])]
        quot = num

    return ' '.join(RtnWords)

if __name__ == '__main__':
    import sys
    for arg in sys.argv[1:]:
        try:
            print ("%10s =>" % (arg,)), CvtNbrToWords(eval(arg))
        except ArithmeticError, e:
            print e
        except Exception, e:
            print e
            print "Usage: %s numbers... for number names in English" % sys.argv[0]
            sys.exit(1)    
_________________________________________________________________



More information about the Python-list mailing list