# Implementing a Decimal class

Discussion in 'C++' started by tajmorton, Dec 17, 2005.

1. ### tajmortonGuest

Hello,
I've decided to try my hand at writing a decimal class that is suitable
for storing weights, money, and time, etc, because I haven't found a
*decimal* class (yes, I know that boost and gmp have rationals, but
that's not exactly easy to use for money and weights)

I'm storing the number in a signed long int, along with another int
called offset which contains where the decimal point goes. So far I
have implemented addition, subtraction, and multiplication. Those were
easy, but I need some tips on how to do division.

I need to calculate as many decimal places as I can without, without
running out of room in long int. I can store only 10 digits... For
example, 1000/362.33 would need to be rounded to 2.759914995, instead
of 618165760657813034839591637137[...]. Any ideas how to actually
implement this?

Also, I'd like some input on if the way I'm doing this is really the
right way, thoughts?

Thanks!
--
Taj

tajmorton, Dec 17, 2005

2. ### Guest

Look at the source for "dc" (Linux).
"dc is a reverse-polish desk calculator which supports unlimited
precision arithmetic."

, Dec 17, 2005

3. ### Viktor PrehnalGuest

I am not sure what you are asking for but for rounding numbers there are
floor() and ceil functions....

tajmorton wrote:
> Hello,
> I've decided to try my hand at writing a decimal class that is suitable
> for storing weights, money, and time, etc, because I haven't found a
> *decimal* class (yes, I know that boost and gmp have rationals, but
> that's not exactly easy to use for money and weights)
>
> I'm storing the number in a signed long int, along with another int
> called offset which contains where the decimal point goes. So far I
> have implemented addition, subtraction, and multiplication. Those were
> easy, but I need some tips on how to do division.
>
> I need to calculate as many decimal places as I can without, without
> running out of room in long int. I can store only 10 digits... For
> example, 1000/362.33 would need to be rounded to 2.759914995, instead
> of 618165760657813034839591637137[...]. Any ideas how to actually
> implement this?
>
> Also, I'd like some input on if the way I'm doing this is really the
> right way, thoughts?
>
> Thanks!

Viktor Prehnal, Dec 17, 2005
4. ### Dietmar KuehlGuest

tajmorton wrote:
> I'm storing the number in a signed long int, along with another int
> called offset which contains where the decimal point goes.

I wouldn't use a limited representation for a decimal class. Instead,
I would use a variable size array of unsigned characters each holding
two decimal digits and a sign stored somewhere.

> So far I
> have implemented addition, subtraction, and multiplication. Those were
> easy, but I need some tips on how to do division.

At least a naive implementation is to use the usual approach to
division you also use when dividing manually. There are more tricky
approach to compute with arbitrary bases and if I remember correctly
Donald Knuth' "Art of Computer Programming" discusses these.
--
<mailto:> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence

Dietmar Kuehl, Dec 18, 2005
5. ### Mathias WaackGuest

tajmorton wrote:

> Hello,
> I've decided to try my hand at writing a decimal class that is
> suitable for storing weights, money, and time, etc, because I
> haven't found a *decimal* class (yes, I know that boost and gmp
> have rationals, but that's not exactly easy to use for money and
> weights)
>
> I'm storing the number in a signed long int, along with another int
> called offset which contains where the decimal point goes. So far I
> have implemented addition, subtraction, and multiplication. Those
> were easy, but I need some tips on how to do division.
>
> I need to calculate as many decimal places as I can without,
> without running out of room in long int. I can store only 10
> digits... For example, 1000/362.33 would need to be rounded to
> 2.759914995, instead of 618165760657813034839591637137[...]. Any
> ideas how to actually implement this?

I'm not sure if you really wants this. I'd assume, if you calculate
an instance of you class as the result of 1000/362.33 (name it x),
what you want is x*362.33 == 1000 and 1000/x == 362.33.
Or suppose someone calculates x 10 times, calculates the sum of these
and divides it by 10. (Its a very common operation while playing
with money - consider invoices, different currencies and a customer
paying multiple invoices at once).

> Also, I'd like some input on if the way I'm doing this is really
> the right way, thoughts?

I think a better way is to store the amounts as fractionals (ie using
two longs for numerator/denominator). So you don't need any division
during an internal calculation. Your results are always correct.
Only the user visible output needs to be rounded.

Mathias

Mathias Waack, Dec 18, 2005