/* ------------------------------------------------------------------ */ /* The 'telco' 0.52 benchmark in C# */ /* ------------------------------------------------------------------ */ /* Copyright (c) IBM Corporation, 2001, 2002. All rights reserved. */ /* ------------------------------------------------------------------ */ /* Call as: */ /* */ /* csTelco [infile [outfile]] [flags] */ /* */ /* where the parameters are: */ /* infile -- input file name [default telco.test] */ /* outfile -- output file name [default telco.outcs] */ /* flags -- may be before or after file names, and may be */ /* */ /* -nocalc -- omit all calculations for each number */ /* -notax -- omit tax calculations (and summations) */ /* */ /* See 'http://speleotrove.com/decimal/telco.html' for background */ /* and details. */ /* */ /* ------------------------------------------------------------------ */ using System; using System.IO; public class csTelco { public static void Main(string[] args) { int numbers; // loop counter DateTime dtStart, dtFinis; // start/end times FileStream inp=null; // files StreamWriter oup=null; // .. decimal sumT, sumB, sumD; // sums decimal n; // number from file decimal p; // price decimal b; // base tax decimal d; // distance tax decimal t; // total price ulong calltype; // 0 or 1 bool calc=true; // 1 for calculations, 0 to skip bool tax=true; // 1 for tax calculations, 0 to skip // call rates, tax rates and other constants decimal baserate=0.0013m; // low call rate decimal distrate=0.00894m; // high call rate decimal basetax =0.0675m; // base tax rate decimal disttax =0.0341m; // distance tax rate string filein ="telco.testb"; // file names string fileou ="telco.outcs"; // .. string str; // output string int j=0; // parameter number for (int i=0; i < args.Length; i++) { if (args[i].StartsWith("-")) { // flag expected if (args[i].Equals("-nocalc")) calc=false; else if (args[i].Equals("-notax")) tax=false; else Console.WriteLine("Flag '{0}' ignored", args[i]); } else { j++; // have a parameter if (j==1) filein=args[i]; // is input file name else if (j==2) fileou=args[i]; // is output file name else Console.WriteLine("Extra parameter '{0}' ignored", args[i]); } } // i; getting arguments Console.WriteLine("telco C# benchmark; processing '{0}'", filein); if (File.Exists(fileou)) File.Delete(fileou); /* ---------------------------------------------------------------- */ /* Benchmark timing starts here */ /* ---------------------------------------------------------------- */ dtStart=DateTime.Now; sumT=0; // zero accumulators sumB=0; sumD=0; // open files try { inp=new FileStream(filein, FileMode.Open, FileAccess.Read); } catch (FileNotFoundException) { Console.WriteLine("Error: file '{0}' not found", filein); return; } try { FileStream ofs=new FileStream(fileou, FileMode.Create, FileAccess.Write); oup=new StreamWriter(ofs); } catch (IOException) { inp.Close(); Console.WriteLine("Error: file '{0}' could not be created", fileou); return; } // From now on, files must be closed explicitly bool Eof=false; /* Start of the by-number loop */ for (numbers=0; ; numbers++) { // get next 8-byte number into n (note: cannot use BinaryReader) try { long num=0; for (int bc=0; bc<8; bc++) { int bx=inp.ReadByte(); if (bx<0) { // EOF Eof=true; break; } num=(num<<8) + bx; } n=num; } catch (IOException) { Console.WriteLine("Error: cannot read file '{0}'", filein); return; } if (Eof) break; if (calc) { calltype=Decimal.ToUInt64(n) & 0x01; // last bit if (calltype==0) { // p=r[c]*n p=baserate*n; } else { p=distrate*n; } p=Decimal.Round(p, 2); // round-half-even to x.xx if (tax) { b=p*basetax*100; // b=p*0.0675 in cents b=Decimal.Truncate(b)/100; // truncate and back to units sumB=sumB+b; t=p+b; if (calltype!=0) { d=p*disttax*100; // b=p*0.0341 in cents d=Decimal.Truncate(d)/100; // truncate and back to units sumD=sumD+d; t=t+d; } } else { t=p; // notax; just copy price } sumT=sumT+t; // total str=t.ToString(); } else { str="0.77"; // nocalc; use simple string } oup.WriteLine(str); // to file } // numbers loop // flush amd close files oup.Flush(); oup.Close(); inp.Close(); /* ---------------------------------------------------------------- */ /* Benchmark timing ends here */ /* ---------------------------------------------------------------- */ dtFinis=DateTime.Now; Console.WriteLine("-- telco C# benchmark result --"); Console.WriteLine(" {0} numbers read from '{1}'", numbers, filein); showUs("Time per number", dtStart, dtFinis, numbers); Console.WriteLine("--"); Console.WriteLine(" sumT = {0}", sumT); Console.WriteLine(" sumB = {0}", sumB); Console.WriteLine(" sumD = {0}", sumD); return; } // Main /* ----------------------------------------------------------------- */ /* Calculate time per iteration and display */ /* */ /* Arg1 is title flag */ /* Arg2 is start time */ /* Arg3 is end time */ /* Arg4 is count (number of iterations) */ /* */ /* Returns the time in microseconds [unscaled] */ /* ----------------------------------------------------------------- */ public static double showUs(String sTitle, DateTime dtStart, DateTime dtFinis, int iCount) { double dDiffns; // float time in ns double dCount=iCount; // count as a double double dUs; // time per iteration in microseconds string sOut; // as formatted string // one tick=100ns dDiffns=Convert.ToDouble(dtFinis.Ticks-dtStart.Ticks)*100; dUs=(dDiffns/dCount)/1000; sOut=String.Format("{0,-16} {1,11:f3}us", sTitle, dUs); Console.WriteLine(" "+sOut+" ["+iCount+"]"); return dUs; } // showus } // class