Canonical way to return values representable in unsigned 64 bit integers

144 views
Skip to first unread message

Michael Bonnet

unread,
Jun 10, 2025, 12:45:39 PMJun 10
to lua-l
I am working on a C API to an embedded system for use in Lua scripting. I have values I need to be able to return to the Lua VM that are 64 bit unsigned integers, and possibly reach into the range that is only representable by the full range of 64 bits. I need the value to not just be readable, but to be usable in arithmetic operations, on the Lua side.

What is the canonical/common way to do this?

Sainan

unread,
Jun 10, 2025, 12:52:54 PMJun 10
to lu...@googlegroups.com
Lua is relatively sane here so it doesn't do any magic conversions to float once values become too big as you may be used to with other languages. Your integers will stay integers.

Additionally, because we use two's complement (guaranteed by the standards since a few years too iirc) you can rely on addition, subtraction, and multiplication to work correctly on negative and positive numbers.

For anything else, you may wish to expose C API functions to handle certain tasks correctly.

-- Sainan

Frank Kastenholz

unread,
Jun 10, 2025, 2:36:12 PMJun 10
to lu...@googlegroups.com

On Jun 10, 2025, at 12:45 PM, Michael Bonnet <maab...@gmail.com> wrote:

I am working on a C API to an embedded system for use in Lua scripting. I have values I need to be able to return to the Lua VM that are 64 bit unsigned integers, and possibly reach into the range that is only representable by the full range of 64 bits. I need the value to not just be readable, but to be usable in arithmetic operations, on the Lua side.

What is the canonical/common way to do this?

Lua uses signed integers, so 0xffffffffffffffff is less than 0. I presume you want it to be greater than 0…

In a past project, where unsigned numbers were needed, we created a new userdata to hold it and then made the appropriate meta functions. 




--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/lua-l/602a0e63-9a2d-485a-9741-2c2a0791eb96n%40googlegroups.com.

bil til

unread,
Jun 11, 2025, 1:29:20 AMJun 11
to lu...@googlegroups.com
Am Di., 10. Juni 2025 um 18:45 Uhr schrieb Michael Bonnet <maab...@gmail.com>:
>
> I am working on a C API to an embedded system for use in Lua scripting. I have values I need to be able to return to the Lua VM that are 64 bit unsigned integers,...


You could quite easily design a Lua "meta class" for 64bit integers,
see Roberto's book "Programming in Lua" Chapter 31 "User-defined Types
in C" - there this is shown for Bit Arrays.

Francisco Olarte

unread,
Jun 11, 2025, 11:28:07 AMJun 11
to lu...@googlegroups.com
Michael:

On Tue, 10 Jun 2025 at 18:45, Michael Bonnet <maab...@gmail.com> wrote:
> I am working on a C API to an embedded system for use in Lua scripting. I have values I need to be able to return to the Lua VM that are 64 bit unsigned integers, and possibly reach into the range that is only representable by the full range of 64 bits. I need the value to not just be readable, but to be usable in arithmetic operations, on the Lua side.
> What is the canonical/common way to do this?

Which arithmetic operations do you needed? It is already been pointed
that addition, subtraction and multiplication work. Equality too.
Comparison is trivial to do in a little function ( negative greater
than non-negative, else normal comparison, IIRC ) and my udivmod is
... thirty lines with comments without pushing it.

Decimal printing may need a bit of work, but with a couple
substractions should be easy....
2^64-1 18446744073709551615
> a=0xffffffffffffffff
> a=-1
> b=0
> c=1000000000000000000
> while(a<0 or a>=c) do b=b+1 a=a-c print(a,b) end
-1000000000000000001 1
-2000000000000000001 2
-3000000000000000001 3
-4000000000000000001 4
-5000000000000000001 5
-6000000000000000001 6
-7000000000000000001 7
-8000000000000000001 8
-9000000000000000001 9
8446744073709551615 10
7446744073709551615 11
6446744073709551615 12
5446744073709551615 13
4446744073709551615 14
3446744073709551615 15
2446744073709551615 16
1446744073709551615 17
446744073709551615 18
It can be done better, just testing it.

Francisco Olarte.

mjmouse9999

unread,
Jun 11, 2025, 10:28:58 PMJun 11
to lua-l
Comparisons can be done with `math.ult`[1] (unsigned less than).

Roberto Ierusalimschy

unread,
Jun 13, 2025, 12:20:00 PMJun 13
to lu...@googlegroups.com
> Comparisons can be done with `math.ult`[1] (unsigned less than).

And printing can be done with '%u':

> string.format("%u", 2 * math.maxinteger)
--> 18446744073709551614

-- Roberto

Gé Weijers

unread,
Jun 14, 2025, 6:02:27 PMJun 14
to lu...@googlegroups.com
Hi,

I think the following does unsigned division correctly. I have not proven it.

local function udivmod(n, d)
    if d < 0 then
        -- d >= 2**63, result can only be 0 or 1
        if math.ult(n, d) then
            return 0, n
        else
            return 1, n - d
        end
    else
        --  estimate division result, can be 1 too low
        local r = ((n >> 1) // d)<<1
        local rem = n - r * d
        if math.ult(rem, d) then
            return r, rem
        else
            return r+1, rem-d
        end
    end
end


--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.


--

Reply all
Reply to author
Forward
0 new messages