3

In c#

double tmp = 3.0 * 0.05;

tmp = 0.15000000000000002

This has to do with money. The value is really 0ドル.15, but the system wants to round it up to 0ドル.16. 0.151 should probably be rounded up to 0.16, but not 0.15000000000000002

What are some ways I can get the correct numbers (ie 0.15, or 0.16 if the decimal is high enough).

Dana
33.1k17 gold badges65 silver badges73 bronze badges
asked Oct 7, 2008 at 16:38

6 Answers 6

14

Use a fixed-point variable type, or a base ten floating point type like Decimal. Floating point numbers are always somewhat inaccurate, and binary floating point representations add another layer of inaccuracy when they convert to/from base two.

answered Oct 7, 2008 at 16:39
Sign up to request clarification or add additional context in comments.

5 Comments

Decimal is a floating point type too. It's just a floating decimal point.
Good to know. Edited to hopefully be a bit more accurate.
Minor nitpick is that they're not 'inaccurate' rather they have a given precision. Just it is more natural for us to think in terms of decimal precision as opposed to binary precision :D
sixlettervariables - I was going to make the same point, but felt I'd been nitpicking too much recently. Basically float/double have a set of exactly representable values - it's just not always the set that developers expect it to be.
Perhaps I should have stated that arbitrary math operations are always a little inaccurate (due to the aliasing to/from representable values, and our tendency to use numbers easily representable in base ten rather than binary)? It's close enough to let it ride, though :)
5

Money should be stored as decimal, which is a floating decimal point type. The same goes for other data which really is discrete rather than continuous, and which is logically decimal in nature.

Humans have a bias to decimal for obvious reasons, so "artificial" quantities such as money tend to be more appropriate in decimal form. "Natural" quantities (mass, height) are on a more continuous scale, which means that float/double (which are floating binary point types) are often (but not always) more appropriate.

answered Oct 7, 2008 at 16:49

Comments

2

In Patterns of Enterprise Application Architecture, Martin Fowler recommends using a Money abstraction

http://martinfowler.com/eaaCatalog/money.html

Mostly he does it for dealing with Currency, but also precision.

You can see a little of it in this Google Book search result:

http://books.google.com/books?id=FyWZt5DdvFkC&pg=PT520&lpg=PT520&dq=money+martin+fowler&source=web&ots=eEys-C_vdA&sig=jckdxgMLSRJtGDYZtcbYST1ak8M&hl=en&sa=X&oi=book_result&resnum=6&ct=result

answered Oct 7, 2008 at 16:44

1 Comment

One thing I like about Fowler's Money pattern is it makes the actual storage type an implementation detail. Cheers
0

'decimal' type was designed especially for this

answered Oct 7, 2008 at 16:41

Comments

0

A decimal data type would work well and is probably your choice.

However, in the past I've been able to do this in an optimized way using fixed point integers. It's ideal for high performance computations where decimal bogs down and you can't have the small precision errors of float.

Start with, say an Int32, and split in half. First half is whole number portion, second half is fractional portion. You get 16-bits of signed integer plus 16 bits of fractional precision. e.g. 1.5 as an 16:16 fixed point would be represented as 0x00018000. Or, alter the distribution of bits to suit your needs.

Fixed point numbers can generally be added/sub/mul/div like any other integer, with a little bit of work around mul/div to avoid overflows.

answered Oct 7, 2008 at 17:01

Comments

0

What you faced is a rounding problem, which I had mentioned earlier in another post

Can I use "System.Currency" in .NET?

And refer to this as well Rounding

answered Oct 8, 2008 at 3:38

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.