Fix issue with unsigned integers

Fixes https://github.com/dlozeve/bqn-npy/issues/1.

The spec says that •bit._cast should support 32-bit uints [1], but
CBQN does not [2].

To get around this, we just use signed integers, which works for
numbers smaller than 2^31. Above that, it will wrap around
and (probably) fail, but CBQN does not support them anyway (except by
converting them to doubles).

From Marshall:

> All of the provided functions at this time are identical on i32 and
> u32, because they work (mod 2^32) and the only difference between
> those formats is to add or subtract 2^32 from numbers outside the
> range [0,2^31).
> If you want to run on u32s stored directly as numbers in BQN (they
> won't fit in i32 and will be stored as double!) you can •bit._cast
> those into a signed format at the beginning and then back out at the
> end.

[1] https://mlochbaum.github.io/BQN/spec/system.html#bitwise-operations
[2] https://matrix.to/#/!EjsgbQQNuTfHXQoiax:matrix.org/$PL2AYNlLQuYhPftdt7yw7rW9heiVEEeATte2zOt2BYk
This commit is contained in:
Dimitri Lozeve 2024-11-11 22:58:04 +01:00
parent 8beeb7d6bd
commit 9a1d251716
3 changed files with 16 additions and 6 deletions

View file

@ -1,12 +1,18 @@
# /// script
# dependencies = ["numpy"]
# ///
import numpy as np
def main():
for endianness in "<>":
for typ in "fiu":
for size in "48":
dtype=endianness + typ + size
arr = np.zeros((2,3,4), dtype=dtype)
dtype = endianness + typ + size
arr = np.zeros((2, 3, 4), dtype=dtype)
np.save(f"test{dtype}.npy", arr)
if __name__ == '__main__':
if __name__ == "__main__":
main()

View file

@ -4,7 +4,11 @@ lf←@+10
magicString(@+147)"NUMPY"
# Type conversions
dtypesformats"<f8","<i4","<u4"64'f',32'i',32'u'
# CBQN does not support other widths than 1 for 'u'. However, signed
# and unsigned integers seem to have the same behavior for numbers
# below 2⋆31.
dtypesformats"<f8","<i4","<u4"64'f',32'i',1'u'
DtypeToFormat{(dtypes<𝕩)formats}
ArrayToBytes{DtypeToFormat 𝕨,8'c'•bit._cast 𝕩}
ArrayFromBytes{8'c',DtypeToFormat 𝕨•bit._cast 𝕩}

View file

@ -1,8 +1,8 @@
SaveNpy,LoadNpy•Import"npy.bqn"
floatArr23•rand.Range 0
intArr50-˜23•rand.Range 100
uintArr23•rand.Range 100
intArr(231)-˜23•rand.Range 232
uintArr23•rand.Range 231
"test_float.npy"SaveNpy floatArr
"test_int.npy"SaveNpy intArr