Frank Millman wrote: > Hi all > > I have a standard requirement for a 'decimal' type, to instantiate and > manipulate numeric data that is stored in a database. I came up with a > solution long before the introduction of the Decimal type, which has > been working well for me. I know the 'scale' (number of decimal > places) of the number in advance. When I read the number in from the > database I scale it up to an integer. When I write it back I scale it > down again. All arithmetic is done using integers, so I do not lose > accuracy. > > There is one inconvenience with this approach. For example, if I have > a product quantity with a scale of 4, and a price with a scale of 2, > and I want to multiply them to get a value with a scale of 2, I have > to remember to scale the result down by 4. This is a minor chore, and > errors are quickly picked up by testing, but it does make the code a > bit messy, so it would be nice to find a solution. > > I am now doing some refactoring, and decided to take a look at the > Decimal type. My initial impressions are that it is quite awkward to > use, that I do not need its advanced features, and that it does not > help solve the one problem I have mentioned above. > > I therefore spent a bit of time experimenting with a Number type that > suits my particular requirements. I have come up with something that > seems to work, which I show below. > > I have two questions. > > 1. Are there any obvious problems in what I have done? > > 2. Am I reinventing the wheel unnecessarily? i.e. can I do the > equivalent quite easily using the Decimal type? > > -------------------- > from __future__ import division > > class Number(object): > def __init__(self,value,scale): > self.factor = 10.0**scale > if isinstance(value,Number): > value = value.value / value.factor
I think this could lead to trouble. One complaint against binary floating point is that it messes up low-order decimal digits, and this ensures that all calculations are effectively done in binary floating point. Better, I think would be if isinstance (value, Number): self.value = value.value self.scale = scale + value.scale and be done with it. Of course, this means self.scale no longer gives the preferred number of fractional digits. My bias: I did a DecimalFloat class way back when, when Decimal was being discussed, and separated the exponent for calculations from the rounding precision for display. Cheers, Mel -- http://mail.python.org/mailman/listinfo/python-list