• Subject: Some thoughts on integer exponentiation (and an implementation)
• From: Stefan Ginsberg <stefanginsberg@...>
• Date: Sat, 13 May 2017 22:16:12 +0200

For the most part I am pleased with Lua's integer implementation.
I do find it lacking in that it does not support "true" integer exponentiation,
so I made an implementation for my own needs. Sharing it here in case
anyone else finds this useful, patched against Lua 5.3.4:
Available from here: http://lua-users.org/files/wiki_insecure/power_patches/5.3/lua-5.3.4_ipow.patch
Also from here: https://pastebin.com/iCKGbZnF

In brief, it makes the '^'-operator perform integer exponentiation using (unsigned)
exponentiation by squaring for two integer operands 'b^n' with a non-negative exponent.
Overflow is ignored, and wraps around to give the same result as repeated multiplication would*.
A negative exponent is handled according to 1 of 3 #define-d modes.
These are either raising an error, converting operation to float, or defining the exponentiation as '1 // (b^abs(n))'.

These modes are the main ideas I have seen proposed for how to handle negative 'n'.
I initially favored the "convert to float" solution as the most useful (and most compatible).
However I now consider the "raise an error" solution to be more useful (see below).
I am unsure if anyone actually wanted the idiv-solution but it is included for completeness.

So why would disallowing "10^-3" be more useful?
First of all, it follows the type-not-value-is-what-matters rule, and '10^-3 == 0.001' breaks that.
I want my integer and float math distinct, and with division one can choose between true-or-integer division to get the desired result.
Unless a new operator ('**' anyone?) is made then something has to give.

Moreover, one could claim that this error-behavior already exists in Lua.
Both '1 // 0' and '1 %% 0' will raise errors instead of "promoting" the operation
to float to represent inf or nan, so why should '10^-3' promote to float to represent a fraction?

Also, it makes '^' behave consistent with an "integer-only" setting. Allowing '^'
to work in such a setting was my motivation for implementing this to begin with,
and '10^-3' behaving differently there is less than ideal.

In my view, integer exponentiation shouldn't be too much of a hassle,
if one is just explicit with the type of numbers used: '10.0^-3.0'

Thoughts?

* That is the intention anyway. If someone notices a case where this doesn't hold,
or some other problem with the algorithm, please let me know!

• Follow-Ups: