Re: numeric precision when raising one numeric to another.

From: Martijn van Oosterhout <kleptog(at)svana(dot)org>
To: Alvaro Herrera <alvherre(at)surnet(dot)cl>
Cc: John Burger <john(at)mitre(dot)org>, pgsql-general(at)postgresql(dot)org
Subject: Re: numeric precision when raising one numeric to another.
Date: 2005-05-19 09:14:06
Message-ID: 20050519091358.GA7748@svana.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-patches

On Wed, May 18, 2005 at 11:32:40PM -0400, Alvaro Herrera wrote:
> On Wed, May 18, 2005 at 10:46:50PM -0400, John Burger wrote:
> > For one thing. For another, I believe the standard C library only has
> > floating point exponentiation functions, not that there aren't plenty
> > of numeric libraries with integral ones. Finally, exponentiated
> > numbers get real big, real fast, and the floating point types can hold
> > much larger magnitudes than the integer types, albeit inexactly. For
> > example, on the Mac I'm using now, long long ints max out at about
> > 10^19, while long doubles can represent 10^308.
>
> Well, we already have an interesting library of mathematical functions
> for NUMERIC (which is an arbitrary precision type, so it wouldn't matter
> how big the result would get). I think the only reason we don't have a
> NUMERIC exponentiation function is that nobody has implemented it.

The prerequisites for such a function would be a log() and exp()
function for numeric. And the real question there would be, what's a
sufficient accuracy? Numbers people actually use rarely have even
rational logarithms, so there is no way to store them 100% accurate.

As long as you're using integral exponents you can get away with
multiplication. BTW, the commandline utility "bc" has arbitrary number
arithmatic, maybe we can see how they do it? It defaults to 20 digits
precision, which is obviously not enough for large exponents.

Hmm, it looks like even they don't support raising to fractional
powers. When calculating 2^100, you need a precision of at least 35
decimal places to get in the ballpark of the correct figure using
log/exp, 30 isn't enough. Maybe do exact for integer exponents and
approx for non-integer?

kleptog(at)vali:~$ bc -l
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
> 2^100
1267650600228229401496703205376
> 2^100.1
Runtime warning (func=(main), adr=11): non-zero scale in exponent
1267650600228229401496703205376
> e(l(2)*100)
1267650600228229400579922894637.90158245154400629512
> scale=30
> e(l(2)*100)
1267650600228229401496703205353.617337311111135194699059124092
> scale=35
> e(l(2)*100)
1267650600228229401496703205375.99897630874075350752485091801369515

Hope this helps,
--
Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
> Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
> tool for doing 5% of the work and then sitting around waiting for someone
> else to do the other 95% so you can sue them.

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Surabhi Ahuja 2005-05-19 10:20:07 analyze at startup?
Previous Message James Croft 2005-05-19 09:07:23 Re: CREATE TABLE problem in plpgsql trigger

Browse pgsql-patches by date

  From Date Subject
Next Message Tom Lane 2005-05-19 23:37:10 Re: Refactoring in lock.c
Previous Message Abhijit Menon-Sen 2005-05-19 06:27:16 Re: md5(bytea)