# math module for Decimals

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sun Dec 28 09:03:29 CET 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

> 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

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

```