开发者

Which type to save percentages

Is it appropriate to use the double 开发者_运维知识库type to store percentage values (for example a discount percentage in a shop application) or would it be better to use the decimal type?


Floating-point types (float and double are particularly ill-suited to financial applications.

Financial calculations are almost always decimal, while floating-point types are almost always binary. Many common values that are easy to represent in decimal are impossible to represent in binary. For example, 0.2d = 0.00110011...b. See http://en.wikipedia.org/wiki/Binary_numeral_system#Fractions_in_binary for a good discussion.

It's also worth talking about how you're representing prices in your system. decimal is a good choice, but floating point is not, for reasons listed above. Because you believe in Object Oriented Programming, you're going to wrap that decimal in a new Money type, right? A nice treatment of money comes in Kent Beck's Test Driven Development by Example.

Perhaps you will consider representing percentages as an integer, and then dividing by 100 every time you use it. However, you are setting yourself up for bugs (oops, I forgot to divide) and future inflexibility (customer wants 1/10ths of a percent, so go fix every /100 to be /1000. Oops, missed one - bug.)

That leaves you with two good options, depending on your needs. One is decimal. It's great for whole percentages like 10%, but not for things like "1/3rd off today only!", as 1/3 doesn't represent exactly in decimal. You'd like it if buying 3 of something at 1/3rd off comes out as a whole number, right?

Another is to use a Fraction type, which stores an integer numerator and denominator. This allows you to represent exact values for all rational numbers. Either implement your own Fraction type or pick one up from a library (search the internet).


You can probably get away with saving the discount percentage as an integer. Just store 10 or 25 or whatever, and when you need to work out the price of something:

newprice = price * discount / 100


decimal does come at a performance cost, but it's usually worth it for financial uses. The reason it has low performance (the worst of all numeric types) is that it doesn't map directly to a hardware type. That means it requires more of the work to be done in software.

Note that it is not only an issue of size. decimal is an integer scaled by a power of 10, while the float and double types are scaled by powers of 2. That means terminating decimal values like 0.1 can be exactly represented using decimal, while they are non-terminating (and thus rounded) for float and double.


I try to avoid floating-point whenever possible. Nothing irritates me more than having .25 not equal to .25, something that happens when you start dealing with them.


A regular float should be fine, unless you need accuracy to like, five decimal places.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜