How to [properly] calculate sales commission in C/C++?

J

Jurek

I have 10+ experience in C/C++ - mostly automation and graphics. I have
never written any business apps though. Recently I've been asked to write a
simple report that would calculate sales commission. The report needs to be
generated from within a C/C++ app. I don't want to mess it up so I thought
maybe someone from this group could give me some advice or point to me to a
place that'll provide some background on the issue.

Here is a description of the problem...
A salesperson sales items for a price (p). Each item category has a
commission rate (r) assigned to it. In a simple way I would calculate a
commission (c) as follows:
c = p * r and then round c to 2 decimal places.
The total for the report would be a sum of all commissions (rounded)
calculated for the items.

Is this the way to do that? Some item prices might be really low and I'm
concerned that floating point arithmetic that can get out of hand. Is
rounding to 2 decimal places a 'standard' in such cases?

I'd appreciate any suggestions,
Thanks
Jurek
 
B

Bruno van Dooren

I have 10+ experience in C/C++ - mostly automation and graphics. I have
never written any business apps though. Recently I've been asked to write
a simple report that would calculate sales commission. The report needs
to be generated from within a C/C++ app. I don't want to mess it up so I
thought maybe someone from this group could give me some advice or point
to me to a place that'll provide some background on the issue.

Here is a description of the problem...
A salesperson sales items for a price (p). Each item category has a
commission rate (r) assigned to it. In a simple way I would calculate a
commission (c) as follows:
c = p * r and then round c to 2 decimal places.
The total for the report would be a sum of all commissions (rounded)
calculated for the items.

Is this the way to do that? Some item prices might be really low and I'm
concerned that floating point arithmetic that can get out of hand. Is
rounding to 2 decimal places a 'standard' in such cases?

If you have to add a long list of floating point values (the standard float
and doubles), the correct approach is to sort them beforehand so that you
add the smallest values first. That way the sum will be closest to the
'real' sum you should have because the precision error will be as small as
possible.

You can use doubles instead of floats to increase precision. that should be
fine for most applications. (simple billing , commsions etc)
Do a google for floating point precision and arithmetic precision if you
want to know the exact limits and errors you will have.

rounding to 2 digits is only done for the end result. not for the
intermediates, except perhaps for displaying purposes.

Of course, If you want to be correct up until the last hunderth of a cent,
you can use System::Decimal (.NET) which was made for financial calculations
that do not allow for rounding errors (bank apps and bookkeeping stuff).
That means you would have to use C++/CLI, though.

--

Kind regards,
Bruno van Dooren
(e-mail address removed)
Remove only "_nos_pam"
 
W

William DePalo [MVP VC++]

Jurek said:
I have 10+ experience in C/C++ - mostly automation and graphics. I have
never written any business apps though. Recently I've been asked to write
a simple report that would calculate sales commission. The report needs to
be generated from within a C/C++ app. I don't want to mess it up so I
thought maybe someone from this group could give me some advice or point to
me to a place that'll provide some background on the issue.

Here is a description of the problem...
A salesperson sales items for a price (p). Each item category has a
commission rate (r) assigned to it. In a simple way I would calculate a
commission (c) as follows:
c = p * r and then round c to 2 decimal places.
The total for the report would be a sum of all commissions (rounded)
calculated for the items.

Is this the way to do that? Some item prices might be really low and I'm
concerned that floating point arithmetic that can get out of hand. Is
rounding to 2 decimal places a 'standard' in such cases?

If your salespeople are not selling fleets of 747s or A300s, in a quick
one-off application I'd expect that most amounts would be held internally as
pennies in 32 bit "int"s. If that doesn't provide sufficient range you could
use the __int64 type.

Of course when it comes time to display the results, the dollar amount comes
from dividing the penny amount by 100, the cents amount is the remainder
modulo 100.

Regards,
Will

Regards,
Will
 
J

Jurek

Bruno, thanks for your input. Unfortunately I can't use C++/CLI. In
regards to rounding... I think I might need to show commission on a per
item basis as well as a report total. If I do not round the commission at
the item level then the report total (i.e. the sum of item commissions)
might not always be correct 'visually' . For example, I might end up with
something like:

item1 0.21
item2. 2.99
item3 0.01
-----------
total 3.22

In reality I don't think that this would happen when the number of items is
so low. On the other hand, with 100ths of items it is almost certain that
the total will be off (visually) by a cent or more. Rounding at the item
level would eliminate the 'visual' problem but would compromise accuracy of
the total (which is probably more important).

Any idea what is appropriate in this case?

Thanks,
Jurek
 
C

Carl Daniel [VC++ MVP]

Bruno van Dooren said:
Of course, If you want to be correct up until the last hunderth of a cent,
you can use System::Decimal (.NET) which was made for financial
calculations that do not allow for rounding errors (bank apps and
bookkeeping stuff).
That means you would have to use C++/CLI, though.

Actually, System.Decimal is nothing more than a wrapper over the OLE
Automation DECIMAL type, which you can use in native C++ programs.

See the functions VarDec* in MSDN at

http://msdn.microsoft.com/library/e...1f-365f-4815-90cc-5f5a7bd91632.asp?frame=true

-cd
 
B

Bruno van Dooren

Bruno, thanks for your input. Unfortunately I can't use C++/CLI. In
regards to rounding... I think I might need to show commission on a per
item basis as well as a report total. If I do not round the commission at
the item level then the report total (i.e. the sum of item commissions)
might not always be correct 'visually' . For example, I might end up with
something like:

item1 0.21
item2. 2.99
item3 0.01
-----------
total 3.22
In reality I don't think that this would happen when the number of items
is so low. On the other hand, with 100ths of items it is almost certain
that the total will be off (visually) by a cent or more. Rounding at the
item level would eliminate the 'visual' problem but would compromise
accuracy of the total (which is probably more important).

Any idea what is appropriate in this case?

If you have several items, it is bound to happen as you say.
Increasing number of digits displayed will not solve that. it will only make
it less obvious, and noticeable only when you have a larger number of items.

It hink the correct approach would be to only display as much decimals as
exist in reality for your currency (0,01 $ or 0.01 Euro for example).

Your end result should be calculated with the'real' values and might end up
not 100% the sum of the individual items, but that cannot be helped. I think
the best you could do would be to place a small note somewhere (or perhaps
mention it in a tooltip popup or help item) that the visual representation
might be a few cents off, but that the end result will be correct. And then
add an explanation of why this is the case.
That way your users will know what is going on if they should ask themselves
the question.

--

Kind regards,
Bruno van Dooren
(e-mail address removed)
Remove only "_nos_pam"
 
J

Jurek

Will, thanks for the suggestion. I have to say that I was thinking of going
with pennies only. The 32bit int is more than I need in this case. My
concern is that I'd still face rounding problems at some point. If, let's
say, a commission on an item is 7% and the price is 12 pennies (0.12) then
the commission amount calculated as:
c = 12 * 7 / 100 will not be very accurate if c is a 32-bit int. Unless,
of course, this is generally acceptable.
Any ideas?

Thanks,
Jurek
 
W

William DePalo [MVP VC++]

Jurek said:
My concern is that I'd still face rounding problems at some point.

Yes, but that is life. In most environments we don't split pennies. So, as
always, a good plan is to defer the rounding until as late as possible in
the life of a transaction. That minimizes the error. And depending on the
application, _best_ case is an error of no more than .5 cents per
transaction.
If, let's say, a commission on an item is 7% and the price is 12 pennies
(0.12) then the commission amount calculated as:
c = 12 * 7 / 100 will not be very accurate if c is a 32-bit int. Unless,
of course, this is generally acceptable.
Any ideas?

Well, you could treat percentages as I propose treating dollar amounts -
scale them up and defer the division until the very end (which narrows the
range of amounts you can deal with, btw)

Of course, it helps to know about the kinds of transactions your application
will process. IIRC the NYSE for many years quoted prices of shares of stock
in eighths of a dollar. As there were no trades on the floor except in
blocks of 100 shares, the fact that a single share may have cost $1.125 was
not cause for concern between "specialists" who moved bazillions of shares a
day because 100 such shares would could $11.25. There was _never_ the
possibility of small rounding errors cascading into something large.

A problem arose only when granny sold her 10 or 12 share portfolio. Then
there was rounding error when the broker / exchange aggregated these small
orders transactions to execute the transaction. But with such a small number
of shares for granny the error for her is "in the noise".

In the end what you do will be determined by the numbers and kinds of
transactions that you expect to handle.

Regards,
Will
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top