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