From: Tom Anderson on 9 May 2010 07:22 On Sat, 8 May 2010, Roedy Green wrote: > If you use double to compute sales taxes, and round to the nearest > penny, there is a gotcha. You are supposed to round a precise half > penny up. This won't work properly for percentage like 6% (0.06) (of > $0.75) which is not precise in binary. > > There a number of ways to avoid problem. Which would you use? I'd start off working in thousandths-of-a-penny using integers (or longs if i thought i might have to deal with amounts above 20 000 dollars). Multiplying by 6% looks like: int salesTaxInPercent = 6; int taxableAmount = ...; int tax = (salesTaxInPercent * taxableAmount) / 100; If that got awkward (and it would, after about three minutes), i'd wrap all amounts in an Amount class that hides all the storage and scaling and so on. When that in turn got awkward, i'd switch to using BigDecimal inside the Amount class. My gut feeling is to keep away from BigDecimal as far as possible, because it adds a lot of complexity you don't need for this. That feeling could well be wrong. tom -- I have often thought that the questions which we were unable to ask and the speeches that we never had a chance to deliver were probably the best ones. -- John Wilkinson MP, on Parliament
From: Arne Vajhøj on 9 May 2010 12:42 On 09-05-2010 07:22, Tom Anderson wrote: > On Sat, 8 May 2010, Roedy Green wrote: >> If you use double to compute sales taxes, and round to the nearest >> penny, there is a gotcha. You are supposed to round a precise half >> penny up. This won't work properly for percentage like 6% (0.06) (of >> $0.75) which is not precise in binary. >> >> There a number of ways to avoid problem. Which would you use? > > I'd start off working in thousandths-of-a-penny using integers (or longs > if i thought i might have to deal with amounts above 20 000 dollars). > Multiplying by 6% looks like: > > int salesTaxInPercent = 6; > int taxableAmount = ...; > int tax = (salesTaxInPercent * taxableAmount) / 100; > > If that got awkward (and it would, after about three minutes), i'd wrap > all amounts in an Amount class that hides all the storage and scaling > and so on. When that in turn got awkward, i'd switch to using BigDecimal > inside the Amount class. > > My gut feeling is to keep away from BigDecimal as far as possible, > because it adds a lot of complexity you don't need for this. That > feeling could well be wrong. BigDecimal is basicly a wrapped BigInteger with a bunch of already implemented rounding rules. Including ROUND_HALF_UP which seems to be what Roedy wants. Arne
From: Jim Janney on 9 May 2010 12:42 Roedy Green <see_website(a)mindprod.com.invalid> writes: > If you use double to compute sales taxes, and round to the nearest > penny, there is a gotcha. You are supposed to round a precise half > penny up. This won't work properly for percentage like 6% (0.06) (of > $0.75) which is not precise in binary. > > There a number of ways to avoid problem. Which would you use? Use BigDecimal for anything involving money. I've heard the excuses for using double and they're all lame. And whatever you do, don't write new BigDecimal(0.06) -- Jim Janney
From: Lew on 9 May 2010 12:49 Arne Vajhøj wrote: > BigDecimal is basic[al]ly a wrapped BigInteger with a bunch of > already implemented rounding rules. > > Including ROUND_HALF_UP which seems to be what Roedy wants. I wonder why he doesn't want accounting rounding. <http://java.sun.com/javase/6/docs/api/java/math/RoundingMode.html#HALF_EVEN> Roedy? -- Lew
From: Arne Vajhøj on 9 May 2010 12:56 On 09-05-2010 12:49, Lew wrote: > Arne Vajhøj wrote: >> BigDecimal is basic[al]ly a wrapped BigInteger with a bunch of >> already implemented rounding rules. >> >> Including ROUND_HALF_UP which seems to be what Roedy wants. > > I wonder why he doesn't want accounting rounding. > <http://java.sun.com/javase/6/docs/api/java/math/RoundingMode.html#HALF_EVEN> I don't know about Canada. Maybe Canada does stuff like that the US way. Or maybe not. In other parts of the world the HALF_EVEN is a "rounding error" in software made in the US. It is not a universal rule. Arne
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Reading from very large file Next: Is the UNNEST function standard and/or widespread? |