[metapost] Built-in functions

Dan Luecking luecking at uark.edu
Fri Sep 29 00:45:22 CEST 2006

At 02:55 PM 9/28/2006, you wrote:
>Hello all, I have been using MetaPost for a while now and quite like
>it. I am using MetaPost 0.641 on a Debian system.
>Built-in functions, as far as I can tell include x**p but I have seen no
>restriction on the value of p. Consequently, I was surprised that
>     for ix=xtmin step ddx until xtmax:
>       ..(ix*ux,((ix-2)**(1/3)+1)*uy)
>     endfor
>     ..((xtmax)*ux,((xtmax-2)**(1/3)+1)*uy);
>in an mp file in an attempt to draw a cube root function lead to an
>error messages:
>! Undefined power: -5**0.33333.

The exponentiation operator is not built-in; it is a macro defined in
plain.mp. It operates on primary expressions. MetaPost's rather
idiosyncratic parsing reads -5 as a primary. It becomes the first
operand one cannot take a real power of a negative number.

You would have no problem with -(5**0.33333).

I have an issue with Knuth definition of **: I think x**y should
produce an exact result when x is an integer and y is a positive
integer. But compare 3**5 and -3**5. The former is approximate
while the latter is exact.

With the present definition (-3)**5 is defined by repeated
multiplication and is exact, but 3**5 is defined via the
mlog and mexp functions. The repeated multiplication technique
used for negative x and positive integer y could also be used for
positive x and positive integer y. It isn't very efficient, so
one would only want it when an exact result is possible, namely
for positive integer x.

Something like:
primarydef x**y =
   if y=2:  x*x
   elseif (x = floor x) and (abs y = floor y):
     1 for n=1 upto y:  *x endfor
   else:  takepower y of x

>Also, is there a built-in log function of any base, can not see one 
>in any documentation?

Where did you look?

There is mlog, a log function with base e**(1/256) (that is, mlog x is
256 times the natural log of x). You can get the log for any base B
by (mlog x)/(mlog B). The purpose of the 256 factor is in the inverse
function: mexp x = e**(x/256). One can do pretty much anything with
mexp that one could with exp, but with less chance of arithmetic
overflow (e**x produces overflow with x as small as 11).


Daniel H. Luecking
Department of Mathematical Sciences
University of Arkansas
"I reject your reality, and substitute my own." -- Adam Savage

More information about the metapost mailing list