answersLogoWhite

0


Best Answer

The following program shows one way to convert to BCD using a variation of packed BCD 8421 encoding. Each digit is represented by 4 bits in the range 0x0 to 0x9. 0xa denotes a minus symbol (for negative values) while 0xb denotes a decimal point for floating point values. The unused value 0xf is used to pad a BCD to a full byte when the number of symbols is odd. Values 0xc, 0xd and 0xe are ignored, but could be used for other purposes such as when representing exponents or fractions/ratios.

Values may be any length, the BCD being represented by a vector of type unsigned char. Since the value of a BCD could easily exceed the range of a long double or a 64-bit integer, conversion to these types is disabled. BCD values are constructed from an input string and converted back to a string for output.

Arithmetic operations can be overloaded to handle a BCD (using decimal notation arithmetic), however this has been left as an exercise for the reader.

#include<iostream>

#include<sstream>

#include<vector>

#include<exception>

using uchar = unsigned char;

class BCD_8421

{

private:

std::vector<uchar> v;

static const uchar lo_mask {0x0f};

static const uchar hi_mask {0xf0};

public:

BCD_8421 (void);

BCD_8421 (const BCD_8421&);

BCD_8421 (BCD_8421&&);

BCD_8421 (const std::string&);

BCD_8421& operator= (const BCD_8421&);

BCD_8421& operator= (BCD_8421&&);

BCD_8421& operator= (const std::string&);

static bool is_valid (const std::string& s);

operator std::string (void) const;

friend std::ostream& operator<< (std::ostream&, const BCD_8421&);

};

BCD_8421::BCD_8421 (void): v(1, 0) {}

BCD_8421::BCD_8421 (const BCD_8421& bcd): v (bcd.v) {}

BCD_8421::BCD_8421 (BCD_8421&& bcd): v (std::move(bcd.v)) {}

BCD_8421::BCD_8421 (const std::string& s): v{} { *this = s; }

BCD_8421& BCD_8421::operator= (const BCD_8421& bcd) { v=bcd.v; return *this; }

BCD_8421& BCD_8421::operator= (BCD_8421&& bcd) { v=std::move(bcd.v); return *this; }

BCD_8421& BCD_8421::operator= (const std::string& s)

{

v.clear();

uchar c {};

bool msb {false};

bool minus {false};

bool point {false};

bool error {false};

bool digit {false};

for (auto i=s.begin(); i!=s.end(); ++i)

{

if (!msb)

c = hi_mask;

uchar x;

switch (*i)

{

case ('0'):

if (!digit)

continue;

case ('1'):

case ('2'):

case ('3'):

case ('4'):

case ('5'):

case ('6'):

case ('7'):

case ('8'):

case ('9'):

digit = true;

x = *i - '0';

break;

case ('.'):

if (!point)

{

point = !point;

x = 10;

break;

}

else

error = !error;

case ('-'):

if (!minus && i==s.begin())

{

minus = !minus;

x = 11;

break;

}

default:

error = !error;

}

if (error)

{

v.clear();

v.push_back (hi_mask);

std::stringstream ss;

ss << "Error: invalid argument in BCD_8421.operator= ("" << s << "")";

throw std::invalid_argument (ss.str());

}

if (msb)

v.push_back ((c & lo_mask) | (x << 4));

else

c |= x;

msb = !msb;

}

if (msb && c)

v.push_back (c);

else if (!digit)

{

v.clear();

v.push_back (hi_mask);

}

return *this;

}

bool BCD_8421::is_valid (const std::string& s)

{

const std::string valid_chars {"0123456789-."};

if (s.find_first_not_of (valid_chars) != valid_chars.npos)

return false;

auto f = s.find ('-');

if (f != s.rfind('-') (f && f!=s.npos))

return false;

if (s.find ('.') != s.rfind('.'))

return false;

return true;

}

BCD_8421::operator std::string (void) const

{

std::stringstream ss;

bool digit {false};

bool point {false};

for (auto i : v)

{

bool msb {false};

do

{

uchar c {};

uchar x = msb ? i >> 4 : i & lo_mask;

switch (x)

{

case (0x0):

case (0x1):

case (0x2):

case (0x3):

case (0x4):

case (0x5):

case (0x6):

case (0x7):

case (0x8):

case (0x9): c = '0' + x; digit = true; break;

case (0xa): c = '.'; point = true; break;

case (0xb): c = '-'; break;

default: break;

}

if (point && !digit)

ss << '0';

if (c) ss << c;

msb = !msb;

} while (msb);

}

if (ss.str().back()=='.')

ss << '0';

return ss.str();

}

std::ostream& operator<< (std::ostream& os, const BCD_8421& bcd)

{

return os << static_cast<std::string> (bcd);

}

int main()

{

for (unsigned loop=0; loop<10; ++loop)

{

std::string input;

while (true)

{

std::cout << "Enter a numeric value: ";

std::cin >> input;

if (BCD_8421::is_valid (input))

break;

std::cerr << "Invalid input.\n";

}

try

{

BCD_8421 a = input;

std::cout << "You entered the value: " << a << std::endl;

}

catch (std::range_error& e)

{

std::cerr << e.what() << std::endl;

}

}

}

User Avatar

Wiki User

10y ago
This answer is:
User Avatar

Add your answer:

Earn +20 pts
Q: How do you convert a decimal into a BCD in C plus plus?
Write your answer...
Submit
Still have questions?
magnify glass
imp
Continue Learning about Engineering

How do you write a c program to convert binary to decimal by using while statement?

write a c++ program to convert binary number to decimal number by using while statement


How do you convert bmp image to jpg by using C or C Plus Plus?

With libbmp and libjpeg. STFW for details.


How do you write program to convert meter to kilometer in c plus plus?

Divide it by 1000.


A c program to convert decimal number to decimal number?

The question asks to do nothing by converting a decimal into itself. Perhaps the question was mistyped. Please restate the question.


How do you convert cents to dollars in C without losing decimal places?

d= c/100; c= c-d*100; c=245 --&gt; d=2, c=45