1

Hey guys,

I'm wondering if there is an exponential function? I've been trying to build my own but it doesn't quite work so I don't know what to do.

P#30558 2016-10-10 14:46 ( Edited 2016-10-13 01:22)

Carets work fine, if that's what you need? ("x=2 print(x^2)" yields "4")

Are you perhaps making overly large numbers? From the manual:

 ```- PICO-8 numbers only go up to 32767.99. // If you add 1 to a counter each frame, it will overflow after around 18 minutes! ```

EDIT:fixed my typo.

P#30559 2016-10-10 15:06 ( Edited 2016-10-10 21:19)

Hmmm what are carats?

I need it for an 3D shape that represents the surface of a vortex. Numbers don't have to be extremely high. They just have to be exponential.

P#30574 2016-10-10 17:05 ( Edited 2016-10-10 21:05)
:: dw817

I gotcher carrot right here. :D

No, truly, a carat is the SHIFT key of 6 "^" so when you use:

 ```PRINT(2^3) ```

you will get back the result of 8. Reversing it, (3^2) gives you 9.

Do you see why, because you need to know the difference in this math to use it properly.

P#30577 2016-10-10 17:12 ( Edited 2016-10-10 21:27)

If you're drawing a 2d swirl, I saw a number of them in the tweetjam thread. If you're moving into 3d, I'll just have to wish you luck.

edit: "logarithmic spiral" might be a helpful phrase as you search.

P#30581 2016-10-10 17:21 ( Edited 2016-10-10 21:23)
:: DrPete

Unfortunately, the caret operator doesn't work for non-integer exponents, e.g.: 16^0.5 evaluates to 1, but you want 4.

I had a go at using Newton-Raphson to approximate an exponential function, but didn't have much success, I think due to bumping up against the limits of 16:16 fixed point.

P#30583 2016-10-10 17:30 ( Edited 2016-10-10 23:38)
:: dw817

Oww ... That really hurts, Dr. Pete. :( I rely on exponents in high decimals to get the proper 'feel' of experience points and ability games when I write RPGs and RPG Makers.

One such routine I wrote in GFA called RIDE:

 ```FUNCTION Ride(I,N,N2#) IF I < 0 OR N <= 0 THEN RETURN 0 IF I + N + N2# = 0 RETURN 0 ENDIF RETURN INT(((I * N + I ^ N2#) \ N) * N) ENDFUNC ```

Lovely, delicious little function I wrote, worked miracles for getting the right curve of growth in numbers.

And you're saying you can't do exponents in decimal values or fractions in PICO ??

Grmmbl ... Are there any kludges yet ?

P#30584 2016-10-10 17:42 ( Edited 2016-10-10 21:43)

Thank you very much, I will try to integrate it!

P#30589 2016-10-10 18:23 ( Edited 2016-10-10 22:23)
1

Here’s a pow() function with decent precision. It relies on sqrt’s precision, and does not use the ^ operator which has terrible precision for large exponents.

 ```function pow(x,a) if (a==0) return 1 if (a<0) x,a=1/x,-a local ret,a0,xn=1,flr(a),x a-=a0 while a0>=1 do if (a0%2>=1) ret*=xn xn,a0=xn*xn,shr(a0,1) end while a>0 do while a<1 do x,a=sqrt(x),a+a end ret,a=ret*x,a-1 end return ret end ```

Some examples:
pow(1.8,-3.7) = 0.1134 (should be 0.113629)
pow(17,1.3) = 39.807 (should be 39.77256)
pow(123,1.7) = 3660.404 (should be 3571.40)
pow(1.3,20) = 189.997 (should be 190.05)
pow(1.1,100) = 13764.307 (should be 13780.61)

P#30791 2016-10-12 19:27 ( Edited 2016-10-12 23:49)
:: dw817

Trying with some fractions and comparing against standard exponents ...

PRINT(7^1.25) -- 7 incorrect
PRINT(POW(7,1.25) -- 11.465 better

Scientific calculator
7^1.25 -- 11.386035931884500202478626418456 accurate

:D This is impressive work, SamHocevar. I'm adding this routine to my list of useful library routines. If I use it you will most definitely receive credit.

NICE JOB !!

P#30802 2016-10-12 21:22 ( Edited 2016-10-13 01:31)
:: sparr
1
P#73323 2020-02-21 19:34

@sparr sure thing! I haven't revisited it in years so it's possible that it can be improved.

P#73329 2020-02-22 01:08
:: Felice
3

@sparr

Not noted in this thread is that zep updated the ^ operator to do proper fractional and negative powers. It actually returns the same values Sam quotes above for his function, so it may be that zep used the same algorithm.

I also wrote a pow() along the same lines a while back. It runs about the same speed as Sam's and gets a slightly better result for the first example he gives, but it's identical for the rest and for dw's numbers. The difference is probably just luck with roundoffs in the order I do the math.

What's important, though, is that the ^ operator takes about 1/4th of the time that either my or Sam's functions take. It took about 6.33 frames to do 10000 calcs with ^, vs about 25.5 with mine or Sam's. Clearly zep is refunding cycles for the operator. So...

Use the handy operator. Don't use a pow() function. :)

P#73346 2020-02-22 11:50 ( Edited 2020-02-22 12:06)
:: sparr

Thanks for the tip. Sometimes it's hard to tell when old stuff on the BBS is still relevant/accurate, and I hadn't taken the time to benchmark this myself yet.

PS: Check out https://github.com/sparr/pico8lib/blob/master/math.p8#L31-L48 if you're interested in accurate fractional exponentiation.

P#73355 2020-02-22 19:52