#-*- coding: UTF-8 -*-
""" Telco Benchmark for measuring the performance of decimal calculations
http://www2.hursley.ibm.com/decimal/telco.html
http://www2.hursley.ibm.com/decimal/telcoSpec.html
A call type indicator, c, is set from the bottom (least significant) bit of the duration (hence c is 0 or 1).
A r, r, is determined from the call type. Those calls with c=0 have a low r: 0.0013; the remainder (‘distance calls’) have a ‘premium’ r: 0.00894. (The rates are, very roughly, in Euros or dollarates per second.)
A price, p, for the call is then calculated (p=r*n). This is rounded to exactly 2 fractional digits using round-half-even (Banker’s round to nearest).
A basic tax, b, is calculated: b=p*0.0675 (6.75%). This is truncated to exactly 2 fractional digits (round-down), and the total basic tax variable is then incremented (sumB=sumB+b).
For distance calls: a distance tax, d, is calculated: d=p*0.0341 (3.41%). This is truncated to exactly 2 fractional digits (round-down), and then the total distance tax variable is incremented (sumD=sumD+d).
The total price, t, is calculated (t=p+b, and, if a distance call, t=t+d).
The total prices variable is incremented (sumT=sumT+t).
The total price, t, is converted to a string, s.
"""
from struct import unpack
from time import clock as time
from decimal import *
import sys, os
# To run the full test with 1,000,000 entries: python telco.py full
test = 'full' not in ' '.join(sys.argv[1:]).lower()
if test:
filename = "telco.testb"
expected = map(Decimal, "8.91 0.50 0.22".split())
print " Time Rate | Price Btax Dtax | Output"
print "------------+----------------------+--------"
else:
filename = "expon180.1e6b"
if not os.access(filename, os.F_OK):
print "You must download and unzip the test file from: http://www2.hursley.ibm.com/decimal/expon180-1e6b.zip"
sys.exit(-1)
expected = map(Decimal, "1004737.58 57628.30 25042.17".split())
getcontext().rounding = ROUND_DOWN
rates = map(Decimal, ('0.0013', '0.00894'))
twodig = Decimal('0.01')
Banker = Context(rounding=ROUND_HALF_EVEN)
basictax = Decimal("0.0675")
disttax = Decimal("0.0341")
infil = open(filename, "rb")
outfil = open("telco.out", "w")
start = time()
sumT = Decimal("0") # sum of total prices
sumB = Decimal("0") # sum of basic tax
sumD = Decimal("0") # sum of 'distance' tax
while 1:
datum = infil.read(8)
if datum == '': break
n, = unpack('>Q', datum)
calltype = n & 1
r = rates[calltype]
p = Banker.quantize(r * n, twodig)
b = p * basictax
b = b.quantize(twodig)
sumB += b
t = p + b
if calltype:
d = p * disttax
d = d.quantize(twodig)
sumD += d
t += d
sumT += t
print >> outfil, t
if test:
print '%6d %1s |%6s %6s %6s |%6s' % (n, 'LD'[calltype], p, b, (not calltype and " " or d), t)
infil.close()
outfil.close()
end = time()
print '\nControl totals:'
print 'Actual ', map(str, (sumT, sumB, sumD))
print 'Expected', map(str, expected)
print 'Elapsed time:', end-start