Others have already said as much, but this is one of those issues that can
withstand overstatement.

When a programmer is asked to "write a program to do something", they need
to not simply map the superficialities of the activity onto the
superficialities of how computers operate.  It is essential for the
programmer to understand the fundamentals of the human-oriented aspects of
the activity and then design a computer-processed approach that uses the
strengths of the computer to best advantage.

This is described nicely by Plauger, in an article briefly summarized at
http://www.drdobbs.com/the-opposite-of-dogma/184415481; though the summary
omits a relevant run of text:

<quote>Trust your customer or systems analyst to tell you how to do it
wrong. You must guard against giving too much weight to these worthy
sources. The problem stems from a lack of abstraction. People tend not to
think in terms of what they want, but focus on one way to get it. Not
knowing the ways of computers, they'll inadvertently limit your options as a
designer.

The problem stems from a lack of abstraction. People tend not to think in
terms of what they want. Rather, they focus on one way to get it. Customers
know how they have run their enterprise for years. They implicitly assume
that every piece of paper, every file, every communications channel is
necessary. They will expect to see those concrete relics captured in various
parts of a computer system. Not knowing the ways of computers, they will
inadvertently closed off your options as a designer.</quote>

Over time, it has become clear that the problem is not merely that of the
"customer", but of the programmers themselves failing to adequately question
their own assumptions about what real-world activities actually entail and
how they should be performed by a computer.

In this case, people accustomed to seeing US currency formatted with a "."
in it leap to the utterly inappropriate and incorrect idea that this should
map to a computer data type which is conventionally represented with a "."
in it, based almost entirely on that superficial visual similarity. When
actually performing manual calculations involving currency, people always do
the thing that makes the most sense -- they calculate in terms of integer
pennies, not floating-point dollars (or else they calculate in integer
dollars and simply round up to cover the pennies when figuring a tip or some
similarly casual amount).  No one would think to perform a manual
calculation involving fractional pennies carried out to 10+ decimal places.
Yet those same people will casually and unthinkingly ask a computer to do
exactly that calculation. (Yet the same people again would not use a more
complicated data type, capable of holding complex numbers or performing
arbitrary-precision calculations.)

The correct approach, in nearly all cases, is to store and calculate
currency using an integer value for the number of pennies involved.
Relatedly, one should simply avoid using the results of division to
determine something like an account balance -- e.g. if one wanted to divide
one account in two, rather than assigning each new account a value of
"old_account/2", one should use that value -- "oa2=old_account/2" -- in
simple subtraction and addition operations --
"account1+=oa2;old_account-=oa2;account2+=oa2;old_account-=oa2;" -- thus
avoiding any "fractional pennies" problems, and also making the operations
that direct affect balances easier to analyze for correctness. (Obviously
real code would have to be safer in a number of ways.)

In rarer cases, like those where a price is specified with hundredths, like
$3.5099, one simply works in an integer number of hundredths of a penny. In
other rare cases involving certain financial instruments, explicit rules or
regulations cover what should be calculated -- in those cases the proper
approach is still not "just do whatever IEEE floating point happens to do".

In a later message, Alex wrote:

> My boss told me not to worry about different currencies yet.  He's pushing
to get the site up asap with the bare necessities.
> I actually have some similar custom code that I'll be using later when I
get more time to implement it (not my first time dealing with international
currencies).

The question here is not one of "bare necessities", but of simply doing this
in a way that can, without ambiguity, be described as utterly wrong.


> -----Original Message-----
> From: Alex Brelsfoard
> 
> I am working on a custom shopping basket, and using Template to multiple
> the quantity of each item by its base price, and then also summing it.
> But I'm losing the floating points.  It's coming out as flat INTs.
> 
> Any idea of how to fix this?



_______________________________________________
Boston-pm mailing list
Boston-pm@mail.pm.org
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to