/* 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