    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Code Review - A Big Number Class</title>
        <link>https://members.accu.org/index.php/articles/884</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 11, #4 - Jun 1999</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c131/">114</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-131/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+131/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Code Review - A Big Number Class</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 June 1999 13:15:31 +01:00 or Thu, 03 June 1999 13:15:31 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e16" id="d0e16"></a></h2>
</div>
<p>Francis passed me a header file for a code critique. The
original author is an experienced C programmer who has been slowly
making a shift to a C++ style of coding. I am told that this was
one of his earlier efforts. I think it is appropriate to keep the
original author's name out of it. I am going to comment on all
aspects of the code including coding style, however I will snip
some places where the code is repetitive.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>First note that though this is a header file it has no sentinel
in the text passed to me. Because some readers are unfamiliar with
such coding details I will comment on them. Every header file
(actually there are rare exceptions to this rule) needs a mechanism
to prevent it being multiply included into the same translation
unit (the thing that the compiler itself sees, after
pre-processing). Conventionally such sentinels are provided by
using a conditional <tt class="literal">#define</tt>. So a header
file mytype.h will start with:</p>
<pre class="programlisting">
#ifndef MYTYPE_H
#define MYTYPE_H
</pre>
<p>The algorithm for generating the sentinel name is to use the
file name in all uppercase letters and replace any illegal
characters (remember that identifiers can only contain letters,
digits and underscores) for identifiers by underscores. The only
time this convention comes unstuck is if you are silly enough to
start a header file's name with a digit. The file will need to have
<tt class="literal">#endif</tt> as its last entry.</p>
<pre class="programlisting">
// #DEFINES
#define MAX_STRING 1050
#define MAX_ALN         32700
#define WORDLENGTH    16      
#define LOGWORDLENGTH  4           
#define MAXNEGWORD     0x8000
</pre>
<p>I am not sure what the following is intended to do. If it was
for some form of conditional compilation I would prefer to see it
always defined (with values of 0 or 1) rather than commented
out.</p>
<pre class="programlisting">
// #define CD_CHECK
</pre>
<p>I find the author's numerical comments curious because the whole
point of using manifest values here (names instead of literal
values) is that the values are irrlelvant. Much more important is
the authors use of all uppercase identifiers. I know this remains
popular but it is fundamentally flawed because it breaches a very
strong coding convention: pre-processor identifiers should never
include a lowercase letter, and all other identifiers should
contain at least one lowercase letter. Sticking to this coding rule
ensures that the pre-processor never tries to replace an
identifier. I know that the Standard C Library breaks this
convention but that is not an excuse for others to do so.</p>
<p>I know this code was written before exceptions and namespaces
became generally available, however now I would expect this kind of
code to be encapsulated in a namespace. It is definitely a mistake
to have that first enum (<tt class="type">signflag</tt>) hanging
out in global space, even in times past it should have been tucked
into the class definition to avoid polluting global space (those
two identifiers 'plus' and 'minus' are far too obvious not to be
replicated somewhere else. In addition defining the enum here means
that it is out of context and should be commented. The same
comments apply to the third enum.</p>
<pre class="programlisting">
// ENUMs
enum signflag { plus, minus };
enum errnum   { OK,  //  0
  NUMBER_TOO_BIG,  //  1
  SUBTRACT_WRONG_WAY,  //  2
  BAD_DIGIT,  //  3
  DIVISION_IMPOSSIBLE_CARRY,  //  4
  UNSUPPORTED_BASE,  //  5
  IMPOSSIBLE_CHAR,  //  6
  OUT_OF_MEMORY,  //  7
  DIVIDE_BY_INTEGER_ZERO,  //  8
  DIVIDE_BY_ALN_ZERO,  //  9
  IMPOSSIBLE_ALN_ALN_MULTIPLY,  // 10
  UNRECTIFIED_ALN_FOUND,  // 11
  SOMETHING_FISHY,  // 12
  CONSTRUCTING_ZERO_ARRAY  // 13
};
enum logic_rep { and_rep, or_rep, xor_rep };
</pre>
<p>If you are unfamiliar with various compilers you may be
surprised by the author's derivation of <tt class="type">aln</tt>
(a very poor name, why not call it <tt class=
"type">VeryLongInt</tt>. If you do not want to type that out
everywhere include <tt class="literal">typedef VeryLongInt
vli;</tt> towards the end of the file) from <tt class=
"classname">CObject</tt>. I guess the author wanted to be able to
use some implementation provided containers. Now that we have the
STL such compiler dependant mechanisms are unnecessary.</p>
<pre class="programlisting">
class aln :public CObject {
  private:
    // private data members
      signflag         m_sign;
      int              m_length;
      unsigned int*   m_digits;
      static int       m_count;   
        // remove once debugged   
      static int       glob_base; 
      // default base for input/output
      static errnum    glob_error;
</pre>
<p>Regular readers will know that I am not enamoured by the use of
prefixes to provide scope information. The usage here seems totally
bizarre. Why <tt class="varname">m_count</tt> but <tt class=
"varname">glob_base</tt>? In addition the comment on the latter
seems completely unhelpful. If you need a comment, ensure it is
meaningful. And why is <tt class="varname">m_digits</tt> a pointer
to <tt class="type">unsigned int</tt>? (also note that <tt class=
"varname">m_length</tt> is a plain <tt class="type">int</tt>).</p>
<pre class="programlisting">
// private member functions
      void rectify();
      bool anew(unsigned);
      bool renew(unsigned);
      void halve();
</pre>
<p>My only problem with these functions is that some of their names
seem less than descriptive. <tt class="function">anew</tt> and
<tt class="function">renew</tt> apparently take an <tt class=
"type">unsigned int</tt> and return a <tt class="type">bool</tt>,
but what do they do?</p>
<p>The following declarations seem to be very badly placed. By
their very nature, friends cannot be private because they are not
members of the class. Declaring them in the private zone of your
class definition is certainly misleading. I will also comment on
the individual blocks because there are lessons to be learnt here
as well.</p>
<pre class="programlisting">
      friend int aln_compare(const aln&amp;, const aln&amp;);
      friend int aln_compare(const aln&amp;, const int);
</pre>
<p>Compare is a symmetric operation, so either there should be just
one version or there must be three. Actually I would favour one as
a <tt class="literal">public</tt> member and renamed '<tt class=
"function">compare</tt>'. As it is a member it has all the required
access and its name is in the class scope so needs no prefix (it
doesn't anyway because the parameter types would provide overload
resolution if the function was (as here) provided in global
scope.</p>
<p>I have reorganised the following so that I can write about a
single block of related functions at one time.</p>
<pre class="programlisting">
      friend errnum aln_add(const aln&amp;, const aln&amp;, aln&amp;);
      friend errnum aln_add(const aln&amp;, const int, aln&amp;);
      friend errnum aln_add(aln&amp;, const int);
// + operators
public:
    aln operator+(const aln&amp;) const;
    aln operator+(const int)  const;
    friend aln operator+(const int, const aln&amp;);
    aln operator+=(const aln&amp;);
    aln operator+=(const int);

      friend errnum aln_subtract(const aln&amp;, const aln&amp;, aln&amp;);
      friend errnum aln_subtract(const aln&amp;, const int, aln&amp;);
      friend errnum aln_subtract(aln&amp;, const int);
// - operators
public:
    aln operator-() const;
    aln operator-(const aln&amp;) const;
    aln operator-(const int)  const;
    friend aln operator-(const int, const aln&amp;);
    aln operator-=(const aln&amp;);
    aln operator-=(const int);
</pre>
<p>I think that the implications of the above is that the whole
design was ill-thought out. As the data separates sign and
magnitude (a perfectly respectable design for representing large
integers) we need two private functions, one to find the difference
between absolute magnitudes and one to find the sum. These should
be <tt class="literal">private</tt> (possibly <tt class=
"literal">protected</tt>) member functions. The logical
declarations are:</p>
<pre class="programlisting">
errnum sum(aln const &amp;);
errnum difference(aln const &amp;);
</pre>
<p>The <span class="returnvalue">errnum</span> return value will be
used to return a success/failure report. You could consider using
exceptions for these, but I can live with this solution (indeed if
you consider failure states to be normal you probably should not
use exceptions at this low level of your implementation/design.
Note that I have not declared these as const member functions
because I intend that the <tt class="type">aln</tt> instance
calling them will be modified.</p>
<p>I will also need two public member functions to provide the
basic operators:</p>
<pre class="programlisting">
aln&amp; operator += (aln const&amp;);
aln&amp; operator -= (aln const&amp;);
</pre>
<p>While I was only provided with a header file, let me look at the
implementation of one of these operator functions:</p>
<pre class="programlisting">
aln&amp; aln::operator += (aln const&amp; rhs){
  errnum err=((m_sign == rhs.m_sign) ?
          sum(rhs) : difference(rhs);
  // process errnum
  return *this;
}
</pre>
<p>The other function is so similar that you might wander if you
could just forward to this one. Actually you could but it would
incur copying the <i class="parameter"><tt>rhs</tt></i> so that you
could negate it. There are various other alternatives, but the
basic principle is to separate out the actual evaluation from the
operator itself.</p>
<p>Once you have the above member functions in place, you can
provide namespace scope functions to provide</p>
<pre class="programlisting">
aln operator+(aln const &amp; , aln const &amp; ); 
aln operator-(aln const &amp; , aln const &amp; ); 
</pre>
<p>Again it may be instructive to examine the implementation of one
of these:</p>
<pre class="programlisting">
aln operator+(aln const &amp; lhs, aln const &amp; rhs){
  aln temp(lhs);
  return temp += rhs;
}
</pre>
<p>Any half way respectable compiler will not burden you with a
using a copy constructor for the return but will use its liberty to
optimise away copy ctors to construct <tt class="varname">temp</tt>
in the location used for the return-by-value temporary. There are
other possibilities, such as operator constructors. Note that the
operator functions should not process exceptions, that is the job
of the calling code.</p>
<p>Once you have done all this, you need to do something similar
for multiplication. Finally you will need to provide division. That
is the one where you will have to work hardest as an implementor.
However note that you should always provide an in-class compound
assignment operator and then forward to that to provide the more
general plain arithmetic operator. There is never any need to use
friend functions to support these simple arithmetic operators. I
know that you will find such abuse of friendship even from
otherwise superb practitioners but that is no excuse to do so
yourself.</p>
<p>&lt; I have snipped the authors multiply and divide declarations
&gt;</p>
<pre class="programlisting">
      friend aln logic_op(const aln&amp; a, const aln&amp; b, const logic_rep oper);
      friend aln cpli(const aln&amp; a);
</pre>
<p>I am far from sure what the code's author intended to do with
the above two functions. Again I find the friend declarations
deeply suspect (and note that these are in the private part of his
class definition.)</p>
<pre class="programlisting">
    // wordshift operators
      aln wordshift_l(const int) const;
      aln wordshift_r(const int) const;
</pre>
<p>Without knowing exactly how the data is being represented
internally (I suspect that it is not in some form of BCD despite
the implications inherent in the identifier <tt class=
"varname">m_digits</tt>) I can only speculate on these two
functions. However I do not think I would use functions with those
declarations, because they necessarily include the construction of
new instances. I think this is the wrong level for that.</p>
<pre class="programlisting">
  public:
      errnum read(const CString&amp;);
      errnum read(const char* const);
      errnum write(char* const) const;
      errnum write(CString&amp;) const;
</pre>
<p>I definitely feel these functions are poorly designed. We should
expect read and write functions to work. So failures are definitely
candidates for exceptions. Of course, I would also change to using
the standard string type instead of an implementation dependant
alternative. I would also clarify the purpose of those functions by
naming them <tt class="function">read_from</tt> and <tt class=
"function">write_to</tt>.</p>
<pre class="programlisting">
    // debugging aids
      void slug() const;
      void slug(char*) const;   
      inline int length() { return m_length; };
</pre>
<p>I have recently moved towards the idea of having debugging
support provided by a separate class that is declared as a friend
of the main class. In that way no debugging overheads are incurred
unless you need them. In addition, adding extra debug functions
only requires recompilation of the debug class followed by
relinking for test code. In other words reduce the dependencies so
that production code is not affected by debug support.</p>
<pre class="programlisting">
// constructors &amp; destructor
      aln();
      aln(const int);
      aln(const unsigned);
      aln(const long);
      aln(const unsigned long);
      aln(const aln&amp;);
      aln(const char * const);  
      aln(const CString&amp; c); 
     ~aln();                 
</pre>
<p>I have some reservations about the provision of all those
constructors. What do you think?</p>
<pre class="programlisting">
      friend aln abs(const aln&amp;);
</pre>
<p>I understand the thinking behind making this a namespace scope
function (so that its use is consistent with that for the built-in
integer types.), but I think it would be better done with a member
function and a forwarding function. So in class I would provide a
public inline function:</p>
<pre class="programlisting">
aln &amp; abs(){ m_sign = plus; return *this)
</pre>
<p>and at namespace scope I would provide:</p>
<pre class="programlisting">
aln abs(const aln &amp; item) {
  aln temp(item);
  return temp.abs();
}
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e204" id="d0e204"></a>Other
operators</h2>
</div>
<p>Note that I moved some operators earlier (add and subtract), and
snipped some of the others (multiply and divide),</p>
<pre class="programlisting">
// = operators
aln operator=(const aln&amp;);
aln operator=(const int);
</pre>
<p>I am very curious about the author's choice here. Almost
everywhere else he supports many integer types. I think for
consistency he should either support assignment from <tt class=
"type">long</tt> and <tt class="type">unsigned long</tt> (there
really is no great value in directly supporting the smaller types,
just let the standard arithmetic conversions do the work for you.)
or he should support none of them and rely on the compiler to
convert from the built-in types to <tt class="type">aln</tt> by
calling an appropriate constructor. The former is more efficient
while the latter may avoid surprises. Note that with the versions
he has declared he will get some very nasty surprises because
<tt class="type">long</tt>, <tt class="type">unsigned long</tt> and
<tt class="type">unsigned int</tt> will all be converted to
<tt class="type">int</tt> (with warnings if the warning level is
set high enough)</p>
<pre class="programlisting">
// bitshift operators
aln operator&gt;&gt;(const int) const;
aln operator&lt;&lt;(const int) const;
aln operator&gt;&gt;=(const int);
aln operator&lt;&lt;=(const int);          
// bitwise operators
aln operator&amp;(const aln&amp;) const;
aln operator&amp;=(const aln&amp;);

aln operator|(const aln&amp;) const;
aln operator|=(const aln&amp;);

aln operator^(const aln&amp;) const;
aln operator^=(const aln&amp;);
aln operator~() const;
</pre>
<p>The above seem reasonable until you realise that some are
symmetrical operators (&amp;, | and ^) which should work with
promotions from built-in types. Those operators should be declared
at namespace scope and forward to the matching compound assignment
operator to do the work (as we did for addition). The shift
operators are fine as member functions, though here also the actual
work should be done by the matching compound assignment.</p>
<pre class="programlisting">
// ! operator
int operator!() const;
// comparison operators
int  operator&lt;(const aln&amp;) const;
int  operator&lt;(const int) const;  
friend int  operator&lt;(const int, const aln&amp;);

int  operator&gt;(const aln&amp;) const;
int  operator&gt;(const  int) const;
friend int  operator&gt;(const  int, const aln&amp;);

int  operator==(const aln&amp;) const;
int  operator==(const  int) const;
friend int  operator==(const  int, const aln&amp;);

int  operator!=(const aln&amp;) const;
int  operator!=(const  int) const;
friend int  operator!=(const  int, const aln&amp;);

int  operator&lt;=(const aln&amp;) const;
int  operator&lt;=(const  int) const;
friend int  operator&lt;=(const  int, const aln&amp;);

int  operator&gt;=(const aln&amp;) const;
int  operator&gt;=(const  int) const;
friend int  operator&gt;=(const  int, const aln&amp;);
</pre>
<p>I do not think that any of these operators should be provided
this way. They are all essentially operators that need to account
for conversions. Each one can be provided by a single namespace
scope operator that uses a public member function that does the
compare. In addition, logical operators should return a <tt class=
"type">bool</tt> value.</p>
<p>For example, replace the last three declarations with a single
(out of class)</p>
<pre class="programlisting">
bool operator &gt;=(aln const &amp; lhs, aln const &amp; rhs);
</pre>
<p>and define it as:</p>
<pre class="programlisting">
bool operator &gt;=(aln const &amp; lhs, aln const &amp; rhs){
return lhs.compare(rhs) &gt;= 0;
}
</pre>
<p>You will almost certainly want to make these inline functions as
they effectively do little more than call the compare function.</p>
<pre class="programlisting">
 // input/output
  friend istream&amp; operator&gt;&gt;(istream&amp;, aln&amp;);
friend 
  ostream&amp; operator&lt;&lt;(ostream&amp;, const aln&amp;);     
</pre>
<p>Well if you have read anything that Francis and I have written
on the subject you will know that we consider using friendship here
as unnecessary and leading to bad habits. Provide the functionality
with member functions <tt class="function">writeTo(ostream
&amp;)</tt> and <tt class="function">readFrom(istream &amp;)</tt>.
Provide the operators with normal namespace functions that forward
to the appropriate member function to do the work.</p>
<pre class="programlisting">
// increment and decrement
      aln operator++();      // prefix  
      aln operator++(int); // postfix 
      aln operator--();      // prefix  
      aln operator--(int); // postfix 
</pre>
<p>Fine.</p>
<pre class="programlisting">
// cast operators
operator int();
operator unsigned();
operator long();
operator unsigned long();
operator CString&amp;();
</pre>
<p>Providing these is almost certainly going to lead to some nasty
surprises. That last one is particularly suspect. Before you
provide a conversion operator (to give them their correct name)
convince yourself that you really, really need it. Then only
provide the smallest number you can manage with. While I might well
provide a function that converted a large integer type to a string
I would never (well almost never) do it via a conversion operator.
Instead I would use a member function <tt class=
"function">toString()</tt>. You really should avoid providing the
compiler with ways to implicitly change one type into another.</p>
<pre class="programlisting">
static void clearerror();
      static void warnerror(errnum);   
      bool no_error() const;
      static void setbase(int);   
      int askbase();   
</pre>
<p>I cannot comment on these because I do not understand their
purpose.</p>
<pre class="programlisting">
};  // end of class aln.
aln power(const aln&amp;, const aln&amp;);
</pre>
<p>Curious, why is this function declared at namespace scope?
Surely it should either be a member function or be granted
friendship (ugh!).</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e284" id="d0e284"></a>Some
Thoughts</h2>
</div>
<p>As I looked at the writer's data I wondered why he had not
provide an array of <tt class="type">signed char</tt> to handle the
data. This would make addition and subtraction relatively easy and
multiplication would be easier (you would know that the result of
multiplying two <tt class="type">signed char</tt> values would fit
into an <tt class="type">int</tt> without overflow.)</p>
<p>For simplicity's sake consider the problem of adding two arrays
(of <tt class="type">signed char</tt>) of equal length that
represent the magnitude of two large integers. (note that I am
coding so that the first element of an array represents the least
significant values)</p>
<pre class="programlisting">
bool addTo(signed char * lhs,
           signed char  const* rhs, length){
  for (int i=0; i!=length; ++i){
    lhs[i] += rhs[i];
    if (lhs[i]&lt;0) {
      lhs[i+1]++;
      lhs[i] |=  0x7F;
    }
  }
}
</pre>
<p>The above code makes a considerable number of assumptions. Can
you list them? Can you refine the idea so as to remove the bugs
that result from these assumptions? How about removing the
assumption that the arrays are of equal length?</p>
<p>Try it and send your results in for publication.</p>
<p>And finally, why should operator functions return by const value
rather than by value?</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
