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:
parent
8beeb7d6bd
commit
9a1d251716
3 changed files with 16 additions and 6 deletions
|
@ -1,5 +1,10 @@
|
||||||
|
# /// script
|
||||||
|
# dependencies = ["numpy"]
|
||||||
|
# ///
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
for endianness in "<>":
|
for endianness in "<>":
|
||||||
for typ in "fiu":
|
for typ in "fiu":
|
||||||
|
@ -8,5 +13,6 @@ def main():
|
||||||
arr = np.zeros((2, 3, 4), dtype=dtype)
|
arr = np.zeros((2, 3, 4), dtype=dtype)
|
||||||
np.save(f"test{dtype}.npy", arr)
|
np.save(f"test{dtype}.npy", arr)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
6
npy.bqn
6
npy.bqn
|
@ -4,7 +4,11 @@ lf←@+10
|
||||||
magicString←(@+147)∾"NUMPY"
|
magicString←(@+147)∾"NUMPY"
|
||||||
|
|
||||||
# Type conversions
|
# Type conversions
|
||||||
dtypes‿formats←⟨"<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.
|
||||||
|
dtypes‿formats←⟨"<f8","<i4","<u4"⟩‿⟨64‿'f',32‿'i',1‿'u'⟩
|
||||||
DtypeToFormat←{(⊑dtypes⊐<𝕩)⊑formats}
|
DtypeToFormat←{(⊑dtypes⊐<𝕩)⊑formats}
|
||||||
ArrayToBytes←{⟨DtypeToFormat 𝕨,8‿'c'⟩•bit._cast 𝕩}
|
ArrayToBytes←{⟨DtypeToFormat 𝕨,8‿'c'⟩•bit._cast 𝕩}
|
||||||
ArrayFromBytes←{⟨8‿'c',DtypeToFormat 𝕨⟩•bit._cast 𝕩}
|
ArrayFromBytes←{⟨8‿'c',DtypeToFormat 𝕨⟩•bit._cast 𝕩}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
⟨SaveNpy,LoadNpy⟩←•Import"npy.bqn"
|
⟨SaveNpy,LoadNpy⟩←•Import"npy.bqn"
|
||||||
|
|
||||||
floatArr←2‿3•rand.Range 0
|
floatArr←2‿3•rand.Range 0
|
||||||
intArr←50-˜2‿3•rand.Range 100
|
intArr←(2⋆31)-˜2‿3•rand.Range 2⋆32
|
||||||
uintArr←2‿3•rand.Range 100
|
uintArr←2‿3•rand.Range 2⋆31
|
||||||
|
|
||||||
"test_float.npy"SaveNpy floatArr
|
"test_float.npy"SaveNpy floatArr
|
||||||
"test_int.npy"SaveNpy intArr
|
"test_int.npy"SaveNpy intArr
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue