math module for Decimals

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sun Dec 28 03:03:29 EST 2008


On Sat, 27 Dec 2008 21:50:09 -0800, jerry.carl.mi wrote:

>> Which math functions? ln, log10, exp, sqrt already exist as methods of
>> Decimal instances. At the end of the Decimal docs there are a few
>> examples, including computing sin and cos (but apparently they naïvely
>> use a McLaurin series like you noticed in other module).
> 
> Hi Gabriel - thanks! For example all goniometric functions are missing.

As my earlier email suggested, the easiest way to fix that is to simply 
write some wrappers that convert floats to decimal.

Of course, that assumes that you don't need more precision than floats 
offer -- it's easy to change the result to get less precision, but if you 
really do need more, then you will need to bite the bullet and find (or 
write) your own trigonometric functions.



> Or the log(x, base).

Easy peasey.

>>> def log(x, base):
...     return x.log10()/Decimal(base).log10()
...
>>> log(Decimal(64), 2)
Decimal('5.999999999999999999999999999')


If that's not accurate enough, you will need to do some additional work:


>>> def log(x, base):  # Warning: INSUFFICIENTLY TESTED
...     power = 1
...     while base**power <= x:
...             power += 1
...     power -= 1
...     x = x/Decimal(base**power)
...     return x.log10()/Decimal(base).log10() + power
...
>>> log(Decimal(64), 2)
Decimal('6')


> Or rand(). 

Generating random numbers is an art in of itself. Again, unless you 
really need the extra precision, just convert the random number to a 
string, then the string to a Decimal.

An alternative is to find one of the many, many published algorithms for 
generating random numbers, and re-write that to use Decimals. However, 
most such algorithms aren't very random; they only give you a little bit 
of randomness, and increasing the precision of the numbers they return 
doesn't make them any more random.


> Sure I can spend time trying to put it
> all together but I thought somebody would have done that already.

I believe they're all waiting for you to do it *wink*

Development of Python is driven by need. If you need something, you can 
make a feature request, or you can build it yourself. But if everyone 
sits around hoping somebody else will develop the feature, nothing will 
ever happen.


> It seems though that the codes that are out there are not ready

Not ready for what? Perhaps they are perfectly ready for the needs of the 
person who wrote them.


> - every one
> of the modules i mentioned above has some issues. Maybe I can put bits
> and pieces together, but if anyone knows of a well proven module (as
> is), I would feel much safer using that (again I am not a mathematician
> and poking into these algorithms makes me feel like trying to fix an
> automatic transmission).

Decimal is a relatively new module for Python, so it's not surprising 
that the functionality is relatively light. But all the hard parts are 
done. If you need extra functionality, you have a number of choices:

(1) Find another way to solve your problem, or lower your expectations. 
(e.g. do you need arbitrary precision?)

(2) Build the extra functionality yourself.

(3) Pay somebody who is an expert to build it.

(4) Ask nicely and hope somebody eventually decides to build it.

(5) Use another language that already provides exactly all the features 
your problem needs.


All of these are valid strategies. Unfortunately, a very popular strategy 
is counter-productive:

(6) Complain loudly that Python is rubbish because it doesn't have the 
functionality you need, and Somebody Better Fix That RIGHT NOW or else 
there will be trouble you betcha.

I recommend against strategy number six :)



-- 
Steven



More information about the Python-list mailing list