Formatting

I am suppose to output the dollar value in Millions and Billions
instead of using the zeros.
For eg 1000,0000 will be displayed as 10Mil  and 100000000 as 100 Mil
100000000,00000 will be displayed as 10Bil 100000000000000
as 100Bil

Thx
d_caesarAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

arnondCommented:
amount1 = 10000000;
amount2 = 10000000000;

a1mil = amount1/1000000;
a2mil = amount2/1000000;
a2bil = amount2/100000000;

cout << a1mil << "mil" << '\n';
cout << a2mil << "mil" << '\n';
cout << a2bil << "bil" << '\n';
-----------------------

this code will produce:

1mil
1000mil
1bil

Hope this helps,
Arnon David.

Of course, amount1 and amount2 should be made as long double.
0
ResonanceCommented:
string suffix;
float dollarvalue;
float newvalue;

if(dollarvalue > 1000000000)
{
  newvalue = dollarvalue / 1000000000;
  suffix = "Bil";
}
else if(dollarvalue > 1000000)
{
  newvalue = dollarvalue / 1000000;
  suffix = "Mil";
}
else
{
  newvalue = dollarvalue;
  suffix = "Dollars";
}

cout << newvalue << suffix << endl;
0
d_caesarAuthor Commented:
I have got it done!! I have utilised Resonance answer.

Thx
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

azamiCommented:
find the highest denomination lower than your dollar value.  Divide the value by that.  Output the quotient, followed by a string appropriate to the denomination:

if val > BILLION
   denom = "Bil"
   outval = val / BILLION
else if val > MILLION
   denom = "Mil"
   outval = val / MILLION
else
   denom = ""
   outval = val

cout << outval << denom
   
0
ResonanceCommented:
If you have used my answer, I'd appreciate you rejecting the other answer and accepting my comment as the answer =)

Thanks...
0
d_caesarAuthor Commented:
Its not flexible!!
0
barrycCommented:
If you want something flexible then try this:

#include <iostream.h>

/**
 * Forward declare the "extractable" class.
 */
class Extractable;

/**
 * Forward declare the base formatter.
 */
template <class T> class Formatter;

/**
 * Forward declare the currency formatter
 */
class CurrencyFormatter;

/**
 * This is a base class that can be derived from to allow an object to be
 * extracted to an output stream.
 */
class Extractable
{
public:
  //----------------------------------------------------------------------------
  // P U B L I C   C O N S T R U C T O R S
  //----------------------------------------------------------------------------
  /**
   * Virtual destructor.
   */
  virtual ~Extractable(void) {}

  /**
   * Method that calls the virtual method <tt>doExtractionTo()</tt> to perform
   * the extraction of this object.
   *
   * @return A reference to the output stream.
   */
  ostream& extractTo(ostream& os) const
  {
    doExtractionTo(os);
    return os;
  }
   
protected:
  //----------------------------------------------------------------------------
  // P R O T E C T E D   C O N S T R U C T O R S
  //----------------------------------------------------------------------------
  /**
   * Default constructor.
   */
  Extractable(void) {}

protected:
  //----------------------------------------------------------------------------
  // P R O T E C T E D   M E M B E R   M E T H O D S
  //----------------------------------------------------------------------------
  /**
   * This method must be overridden to enable extraction.
   *
   * @param os The output stream to write to.
   */
  virtual void doExtractionTo(ostream& os) const = 0;
 
private:
  //----------------------------------------------------------------------------
  // P R I V A T E   C O N S T R U C T O R S / O P E R A T O R S
  //----------------------------------------------------------------------------
  /**
   * Hidden copy constructor.
   *
   * @param e The extractable object.
   */
  Extractable(const Extractable& e) {}

  /**
   * Hidden assignment operator.
   *
   * @param e The extractable object.
   * @return A reference to self.
   */
  Extractable& operator=(const Extractable& e) { return *this; }
};

/**
 * Extractor operator for any extractable object.
 *
 * @param os The output stream to extract to.
 * @param e A constant reference to the extractable object.
 * @return A reference to the output stream.
 */
ostream& operator<<(ostream& os, const Extractable& e)
{
  return e.extractTo(os);
}

/**
 * This class is a base class used to provide a flexible means of formatting
 * objects and types.  The template type T must provide a copy constructor
 * and assignment operator.
 * <br><b>EXAMPLE:</b><br><pre>
 * class CurrencyFormatter : public Formatter<signed long> {
 *  . . .
 * protected:
 *   virtual ostream& extractValue(ostream& os, signed long value);
 * };
 *
 */
template <class T>
class Formatter {
public:
  //----------------------------------------------------------------------------
  // P U B L I C   I N N E R   C L A S S E S
  //----------------------------------------------------------------------------
  /**
   * This inner class is used as a temporary for streaming objects to output
   * streams.
   */
  class Bridge : virtual public Extractable
  {
  public:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // F R I E N D S
    /**
     * Make <tt>Formatter< T ></tt> a friend so it can construct these.
     */
    friend class Formatter<T>;

  public:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // P U B L I C   C O N S T R U C T O R S / D E S T R U C T O R S
    /**
     * Copy constructor.
     *
     * @param b The bridge to copy.
     */
    Bridge(const Formatter<T>::Bridge& b)
        : formatter_(b.formatter_), value_(b.value_) {}

    /**
     * Virtual destructor.
     */
    virtual ~Bridge(void) { }

    /**
     * Assignment operator.
     *
     * @param b The bridge to copy.
     * @return A reference to self.
     */
    Bridge& operator=(const Formatter<T>::Bridge& b)
    {
      formatter_ = b.formatter_; value_ = b.value_; return (*this);
    }

  public:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // P U B L I C   M E M B E R   M E T H O D S
    /**
     * This method is provided to allow the formatter to format the value to
     * the output stream.
     *
     * @param os The output stream to write to.
     * @return A reference to self.
     */
    virtual void doExtractionTo(ostream& os) const
    {
      (formatter_)->extractValue(os, value_);
    }
   
  private:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // P R I V A T E   C O N S T R U C T O R S
    /**
     * Standard constructor for <tt>Formatter</tt> to use.
     *
     * @param f The formatter.
     * @param v the value.
     */
    Bridge(Formatter& f, T v) : formatter_(&f), value_(v) {}

  private:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // P R I V A T E   M E M B E R   D A T A
    /**
     * The formatter to use.
     */
    Formatter* formatter_;

    /**
     * The value.
     */
    T value_;
  };  

public:
  //----------------------------------------------------------------------------
  // F R I E N D S
  //----------------------------------------------------------------------------
  /**
   * Make the bridge class a friend so it can see the <tt>extractValue()</tt>
   * method.
   */
  friend class Bridge;
 
public:
  //----------------------------------------------------------------------------
  // P U B L I C   D E S T R U C T O R
  //----------------------------------------------------------------------------
  /**
   * Virtual destructor.
   */
  virtual ~Formatter(void) {}

public:
  //----------------------------------------------------------------------------
  // P U B L I C   M E M B E R   M E T H O D S
  //----------------------------------------------------------------------------
  /**
   * This method obtains the bridge that may be sent to the output stream to
   * format the value.
   *
   * @param value The value to format.
   * @return A temporary bridge that can be sent to the output stream.
   */
  Formatter<T>::Bridge format(T value)
  {
    return Bridge(*this, value);
  }

protected:
  //----------------------------------------------------------------------------
  // P R O T E C T E D   C O N S T R U C T O R S
  //----------------------------------------------------------------------------
  /**
   * Default constructor which is visible to the deriving class.
   */
  Formatter(void) {}

protected:
  //----------------------------------------------------------------------------
  // P R O T E C T E D   M E M B E R   M E T H O D S
  //----------------------------------------------------------------------------
  /**
   * This virtual method must be overridden to handle the formatting of the
   * templated object.
   *
   * @param os The output stream to write to.
   * @param value The value to write.
   * @return A reference to the specified output stream.
   */
  virtual void extractValue(ostream& os, T value) const = 0;

private:
  //----------------------------------------------------------------------------
  // P R I V A T E   C O N S T R U C T O R S
  //----------------------------------------------------------------------------
  /**
   * Hidden copy constructor.
   *
   * @param f The formatter to copy.
   */
  Formatter(const Formatter<T>& f) {}

  /**
   * Hidden assignment operator.
   *
   * @param f The formatter to copy.
   * @return A reference to self.
   */
  Formatter<T>& operator=(const Formatter<T>& f) { return *this; }
};

/**
 * This class is a specialization of <tt>Formatter< signed long ></tt> that is
 * used to format signed long integers as currencies.
 *
 * <br><b>EXAMPLE:</b><br><pre>
 * void foo(void) {
 *   CurrencyFormatter formatter;
 *
 *   signed long dollars1 = 1000000000L;
 *
 *   cout << formatter.format(dollars) << endl;
 *
 * }
 * </pre>
 */
class CurrencyFormatter : virtual public Formatter<signed long>
{
public:
  //----------------------------------------------------------------------------
  // P U B L I C   S T A T I C   C O N S T A N T S
  //----------------------------------------------------------------------------
  /**
   * This is the currency symbol, actually this should be part of some Locale
   * object, but we include it in this class to support U.S. Currency only for
   * the sake of simplicity.
   */
  static const char* const CURRENCY_SYMBOL;

  /**
   * Constant value for one million.
   */
  static const signed long ONE_MILLION;

  /**
   * Constant value for one billion.
   */
  static const signed long ONE_BILLION;

  /**
   * String suffix to be appended to amounts over one-million.
   */
  static const char* const MILLION_SUFFIX;
 
  /**
   * String suffix to be appended to amounts over one-billion.
   */
  static const char* const BILLION_SUFFIX;
 
  /**
   * String suffix to be appended to amounts which do not get a suffix.
   */
  static const char* const NO_SUFFIX;
 
public:
  //----------------------------------------------------------------------------
  // P U B L I C   C O N S T R U C T O R S / D E S T R U C T O R S
  //----------------------------------------------------------------------------
  /**
   * The default constructor.
   */
  CurrencyFormatter(void) {}

  /**
   * Copy constructor.
   *
   * @param cf The currency formatter to copy.
   */
  CurrencyFormatter(const CurrencyFormatter& cf) {}

  /**
   * Virtual destructor.
   */
  virtual ~CurrencyFormatter(void) {}
 
public:
  //----------------------------------------------------------------------------
  // P U B L I C   M E M B E R   O P E R A T O R S
  //----------------------------------------------------------------------------
  /**
   * Assignment operator.
   *
   * @param cf The currency formatter to copy.
   * @return A reference to self.
   */
  CurrencyFormatter& operator=(const CurrencyFormatter& cf)
  {
    return (*this);
  }

protected:
  //----------------------------------------------------------------------------
  // P R O T E C T E D   M E M B E R   M E T H O D S
  //----------------------------------------------------------------------------
  /**
   * Implemented from <tt>Formatter< signed long ></tt> to format
   * <tt>signed long</tt> values as currencies.
   */
  virtual void extractValue(ostream& os, signed long value) const
  {
    unsigned long absValue = (unsigned long) ((value<0) ? -value : value);
   
    const char* suffix = NO_SUFFIX;
    if (absValue > ONE_BILLION)         suffix = BILLION_SUFFIX;
    else if (absValue > ONE_MILLION)    suffix = MILLION_SUFFIX;
   
    if ( absValue > ONE_MILLION ) {
      value = (value > 0) ? 1 : -1;
    }
   
    os << CURRENCY_SYMBOL << " " << value << " " << suffix;
  }  

};

const char* const CurrencyFormatter::CURRENCY_SYMBOL = "$";

const signed long CurrencyFormatter::ONE_MILLION = 1000000L;

const signed long CurrencyFormatter::ONE_BILLION = 1000000000L;

const char* const CurrencyFormatter::MILLION_SUFFIX = "Mil";

const char* const CurrencyFormatter::BILLION_SUFFIX = "Bil";
 
const char* const CurrencyFormatter::NO_SUFFIX = "";
 
int main(int argc, const char* argv)
{
  CurrencyFormatter formatter;

  signed long posValue0 = CurrencyFormatter::ONE_MILLION / 4;
  signed long posValue1 = CurrencyFormatter::ONE_MILLION * 3;
  signed long posValue2 = CurrencyFormatter::ONE_BILLION * 2;

  signed long negValue0 = CurrencyFormatter::ONE_MILLION / -4;
  signed long negValue1 = CurrencyFormatter::ONE_MILLION * -3;
  signed long negValue2 = CurrencyFormatter::ONE_BILLION * -2;
 
  cout << formatter.format(posValue0) << endl;
  cout << formatter.format(posValue1) << endl;
  cout << formatter.format(posValue2) << endl;
 
  cout << formatter.format(negValue0) << endl;
  cout << formatter.format(negValue1) << endl;
  cout << formatter.format(negValue2) << endl;
 
return 0;
}
0
ResonanceCommented:
Good grief, barryc.  How long did it take you to write that?

Meaning no offense, but that's what I would consider a serious abuse of C++, kind of like using a howitzer to kill a horsefly.  More code (flexible or not) != good code.
0
barrycCommented:
I actually had that written for something I am writing so I thought I would share it since my Formatter class and Extractable class are applicable to the question at hand.  I figure, why not share the code.

The Extractable class acts an "interface" to make any object writable to an output stream.

The Formatter also acts as an interface and is the base class that defines how to format an object of a particular type.

The Formatter<T>::Bridge class is a temporary object that gets constructed as a place holder to simplify formatting the object to the stream.

Finally, the CurrencyFormatter (which I had to write specific to this question) is the specialization of the formatter that does what d_caesar asks.

It looks like alot, but I've had it for a while.  The framework would allow someone to change out formatters of a particular type quite easily.  

Finally, I included a test program.  I wouldn't call it an abuse of C++.  It's just an object-oriented approach.

BTW: I hide the copy constructor and asisgnment operators on the "interface" classes which are used as "virtual" base classes.  The reason for this is to simplify derivation by limiting the user to the default constructor and to emphasize the fact that these classes do not contain any state.  The JavaDoc style comments are used because I use Doxygen to produce documentation pages and I didn't bother removing them.

0
d_caesarAuthor Commented:
I am impressed and greatly appreciative. Dear barryc please sumbit your comment as answer and let me have the honor to give you the points.

Thanking you very very much.....
0
barrycCommented:
See my comment on Tuesday, December 07 1999 - 01:58PM PST for complete answer.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
barrycCommented:
One correction to the "extractValue()" method of CurrencyFormatter:
================================================
protected:
  //----------------------------------------------------------------------------
  // P R O T E C T E D   M E M B E R   M E T H O D S
  //----------------------------------------------------------------------------
  /**
   * Implemented from <tt>Formatter< signed long ></tt> to format
   * <tt>signed long</tt> values as currencies.
   */
  virtual void extractValue(ostream& os, signed long value) const
  {
    unsigned long absValue = (unsigned long) ((value<0) ? -value : value);
    unsigned long fraction = 0;
   
    const char* suffix = NO_SUFFIX;
    if (absValue > ONE_BILLION)         suffix = BILLION_SUFFIX;
    else if (absValue > ONE_MILLION)    suffix = MILLION_SUFFIX;
   
    if ( absValue > ONE_BILLION ) {
      fraction = absValue % ONE_BILLION;
      value = value / ONE_BILLION;
    }
    else if (absValue > ONE_MILLION) {
      fraction = absValue % ONE_MILLION;
      value = value / ONE_MILLION;
    }

    while ((fraction != 0) && ((fraction %10) == 0)) {
      fraction /= 10;
    }
   
    os << CURRENCY_SYMBOL << " " << value;
    if (fraction != 0) {
      os << "." << fraction;
    }
    os << " " << suffix;
  }  
================================================
Here is the modified test program.  Sorry I didn't catch this on the first try.
================================================
int main(int argc, const char* argv)
{
  CurrencyFormatter formatter;

  signed long posValue0 = CurrencyFormatter::ONE_MILLION / 4;
  signed long posValue1 = CurrencyFormatter::ONE_MILLION * 3;
  signed long posValue2 = CurrencyFormatter::ONE_BILLION * 2;
  signed long posValue3 = CurrencyFormatter::ONE_BILLION / 400;

  signed long negValue0 = CurrencyFormatter::ONE_MILLION / -4;
  signed long negValue1 = CurrencyFormatter::ONE_MILLION * -3;
  signed long negValue2 = CurrencyFormatter::ONE_BILLION * -2;
  signed long negValue3 = CurrencyFormatter::ONE_BILLION / -400;
 
  cout << formatter.format(posValue0) << endl;
  cout << formatter.format(posValue1) << endl;
  cout << formatter.format(posValue2) << endl;
  cout << formatter.format(posValue3) << endl;
 
  cout << formatter.format(negValue0) << endl;
  cout << formatter.format(negValue1) << endl;
  cout << formatter.format(negValue2) << endl;
  cout << formatter.format(negValue3) << endl;
 
return 0;
}

0
barrycCommented:
This fix should allow for "fractional" millions and billions, such as 2.5 million, 3.333333 million, etc...

This CurrencyFormatter can be defined to derive from Formatter<double> and you can use double to represent all of your amounts.  Be careful when using doubles though since floating point math leads to some odd rounding problems due to the imperfect representation of decimal numbers in a binary register.

I have found that short of writing a "BigDecimal" class to handle large precision decimal numbers, that using a long integer to represent the number of PENNIES is the most straight-forard way to store monetary amounts.  This may not work with for you unless you platform has 64-bit longs since the maximum dollar amount that can be represented this way is about 20.1 million dollars.

0
d_caesarAuthor Commented:
Dear barryc , The compiler is giving me error at this line      cBridge(const cFormatter<T>::cBridge& b): formatter_(b.formatter_), value_(b.value_) {}

error C2629: unexpected 'class cFormatter<long>::cBridge ('
: see reference to class template instantiation cFormatter<long>' being compiled

Did you compiled the progam before sending it to me...

Thx
Caesar
0
MindBladeCommented:
d_caesar - in fairness you should award the answer to resonance. and post a reward question to barry_c as well.
Just my .02
0
barrycCommented:
MindBlade is right about the points.  I see in the above comments you state "I have used Resonnance's answer".  If you are using his comment as the answer (and I do base my "CurrencyFormatter::extractValue()" implementation off of Resonance's answer, then Resonance deserves some points too).  You can do this by rejecting my answer, allow Resonance to answer and accept, and then if you like offer a second question worth however many points you want that I can answer.   If you don't want to award any more than 30 points then just give them to Resonance.


As far as the compiler goes... I compiled the code on SunPro CC 4.2 on Solaris.  It also compiles under g++ 2.8.1.  What compiler are you using?

A simple fix might be to replace "Formatter<T>::Bridge" with simply "Bridge" in the copy constructor and the assignment operator declarations that use "Formatter<T>::Bridge" in their declaration.  Since we are within the scope of "Formatter<T>::Bridge" it should resolve the name "Bridge" to "Formatter<T>::Bridge" automatically.

Let me know if this works.  If not there are a couple of other adjustments that could probably be made to get this code by your compiler.

===============================================================
template <class T> class Formatter {
  . . .
  class Bridge : virtual public Extractable
  {
  public:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // F R I E N D S
    /**
     * Make <tt>Formatter< T ></tt> a friend so it can construct these.
     */
    friend class Formatter<T>;

  public:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // P U B L I C   C O N S T R U C T O R S / D E S T R U C T O R S
    /**
     * Copy constructor.
     *
     * @param b The bridge to copy.
     */
    Bridge(const Bridge& b) // *** CHANGED THIS ***
        : formatter_(b.formatter_), value_(b.value_) {}

    /**
     * Virtual destructor.
     */
    virtual ~Bridge(void) { }

  public:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // P U B L I C   M E M B E R   O P E R A T O R S
    /**
     * Assignment operator.
     *
     * @param b The bridge to copy.
     * @return A reference to self.
     */
    Bridge& operator=(const Bridge& b)  // *** CHANGED THIS ***
    {
      formatter_ = b.formatter_; value_ = b.value_; return (*this);
    }
  . . .
};
0
d_caesarAuthor Commented:
I am impressed! Thx a lot
0
barrycCommented:
I will be posting a 30 point question for Resonance to answer.  Please check the C++ group.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.