Listing 2 Implementation of class BCD

/* bcd.cpp                                      */
/* Use CL.BAT to build program -- CL bcd bcdops */
/* Copyright 1994 - Mark R. Parker              */
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include "bcd.h"
#define FALSE 0
#define TRUE (!(FALSE))
#define MINUS (BYTE) 0X80
#define PLUS (BYTE) 0X00
#define MAX_DIGITS 18
#define NUM_BYTES 10
#define LAST_BYTE (NUM_BYTES - 1)

extern "C" { void BCDAdd(BCD, BCD, BCD&); }

ostream& operator <<(ostream& out, const BCD& BCDVal)
{ BCDVal.BCDPut(); return out;  }

istream& operator >>(istream& in, BCD& BCDVal)
{ BCDVal.BCDGet(); return in;   }

BCD::BCD(char * str)
{ int len = strlen(str), start = 0, digits = len;
  BYTE tempdigit;
  
  DigPairs = new BYTE[NUM_BYTES];
  for (int i = 0; i < NUM_BYTES; ++i)
    DigPairs[i] = 0x00;          // Init array to 0
  if (len == 0) return;          // No initial string
  if (str[0] == '-') {           // Is str negative?
    DigPairs[LAST_BYTE] = MINUS;
    digits = len - 1;            // 0th char not
    start = 1;                   // a digit
    }
  else if (str[0] == '+') {      // Is str positive?
    digits = len - 1;            // 0th char not
    start = 1;                   //   a digit
    }
  int pairs = digits / 2;
  int odd_len = digits % 2;
  if (odd_len)                   // Pack only 1 digit
    DigPairs[pairs] = str[start--] - '0';
  else  {                        // Pack 2 digits
    DigPairs[pairs - 1] =
      16*(str[start] - '0') + str[start+1] - '0';
    pairs--; }
  for (i = 1; i <= pairs; ++i)  { // Move remaining prs
    tempdigit = 16 * (str[start + 2*i] - '0');
    tempdigit += str[start + 1 + 2*i] - '0';
    DigPairs[pairs - i] = tempdigit;
    }
}

BCD& BCB::operator=(const BCD& BCDVal)  // Assignment
{ for (int i = 0; i < NUM_BYTES; ++i)
    DigPairs[i] = BCDVal.DigPairs[i];
  return (*this); }

BCD& BCD::operator+(const BCD& BCDVal) //Addition
{ static BCD Store;
  BCDAdd(*this, BCDVal, Store);
  return (Store); }

void BCD::BCDGet()
{ int i, j, ch1, ch2, len, errflag = 0;
  BYTE pair, sign;
  char digit[MAX_DIGITS];

  ch1 = getche();                 // Inspect first
  errflag = FALSE;                // character
  if (ch1 == 0xd) return;         // Just return
  if (ch1 == '-') sign = MINUS;   // Neg. no.
  else if ( (ch1 == '+') || (ch1 == ' ') ||
    (ch1 >= '0' && ch1 <= '9') ) sign = PLUS;
  else errflag = TRUE;    // Error occurred to get here
  int start = 0;
  if (ch1 >= '1' && ch1 <= '9') { // If ch1 was digit,
    digit[0] = (char) ch1;        // just read
    start = 1;                    // remaining digits
    }
  for (i = start; i < MAX_DIGITS; i++) {
    ch2 = getche();
    if (ch2 == 0xd) {             // Put 0 if
      digit[i] = 0;              //  Enter was pressed
      break;
      }
    digit[i] = (char) ch2;
    }

  DigPairs[LAST_BYTE] = sign;   // Set the sign
  len = i;                      // len digits in string
  if ((len % 2) == 0) {         // Even length.
    for (j = 0; j < len / 2; j++) {   // peel off pairs
      pair = (digit[2*j] - '0') ' 0x10
          + (digit[2*j+1] - '0');
      DigPairs[len / 2 - 1 - j] = pair;
      }
    }
  else {                        // Odd length
    DigPairs[len / 2]= digit[0] - '0';  // Move 1 byte
    for (j = 1; j < len / 2 + 1; j++) {   // Move other
      pair = (digit[2*j - 1] - '0') * 0x10
          + (digit[2*j] -'0');           //   pairs
      DigPairs[len / 2 - j] = pair;
      }
    }
  putc('\n', stdout):
}

void BCD::BCDPut() const
{ if (DigPairs[LAST_BYTE])       // If negative,
    putc( '-', stdout);         // write minus sign
  else putc(' ', stdout);       // Else, put space
  for (int i = LAST_BYTE - 1; i >= 0; i--) {
    if (DigPairs[i] < 10) putc('0', stdout);
    printf("%x", DigPairs[i]);
    }
  putc('\n', stdout);
}                        // End of File BCD.CPP
// End of File