lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

If you are working on a self-contained project, you can probably obtain most of the functionality that you want by adding a metatable for light userdata that can override __eq, then you can use these to hold your "integers". This would allow you to work with "unboxed" small integers (since "void *" is a uintptr_t) if that's a performance issue. As an added bonus, this fixes Andrew's concern: the light-userdata metatable __mul and __add can detect overflow and substitute a full userdata MPI object.

Alternatively, you could just patch it so that all integer arithmetic is bignum by default (I think Python does this?). This would probably be the fastest approach, and allows you to optimize more aggressively for the situation you're concerned with. Lua is meant to be modifiable.

However, if you're distributing this, I think that people are correctly very wary of making the "==" operator do something other than checking for equality. It can introduce security issues in old code, for example, if I pass an object with a metamethod that overrides "==" to a function that uses this to validate input. One alternative would be to introduce a new "equivalence" operator which can be overridden -- _javascript_ and PHP both did this, IIRC. An easy hack would be to just use __bxor (~), which already looks kind of like equality.

-Mason

On Thu, Jun 9, 2022 at 8:43 AM Andrew <ajc@gmx.net> wrote:
Hi Tomás,

I think you are saying that if a number fits in a Lua integer then the
mpi module should simply return an integer.

But now what happens when we multiply two numbers which both fit in a
Lua integer but the product does not.

mpi(1000000000000000) * mpi(1000000000000000) -> ?

If the two operands were converted to Lua integers then the result would
just overflow, because Lua doesn't know that they are supposed to be big
integers! That would defeat the whole object of the mpi module.

Of course my example of mpi(1) == 1 is trivial. In general we might have
a complex big integer calculation which we are comparing with an integer
constant, eg:

local a = <some mpi calculation>
if (a == 137)
...

So the numbers have to stay in mpi format even if they would fit into a
Lua integer.

-a


On 09/06/2022 20:46, Tomás Guisasola wrote:
> Hi Eduardo and Andrew
>
>>> But there's a problem when comparing for equality, because the __eq
>>> metamethod is only called when _both_ operands are tables or userdata!
>>>
>>> if a == 1 then          -- metamethod __eq
>>>          print "true"
>>> else
>>>          print "false"
>>> end
>>> [ false ]
>
> What I didn't understand is why you have to represent the number 1 as
> a table.  In other words, why don't you make the result of `mpi(1)` be
> the number 1 ?
>
> Regards,
> Tomás