J x-type: how are they stored internally?

I encode some J bindings in Python ( https://gist.github.com/Synthetica9/73def2ec09d6ac491c98 ). However, I ran into a problem while processing integers of arbitrary numbers: the result does not make any sense. This is something different every time (but in the same total amount). Corresponding code snippet:

def JTypes(desc, master): newdesc = [item.contents.value for item in desc] type = newdesc[0] if debug: print type rank = newdesc[1] shape = ct.c_int.from_address(newdesc[2]).value adress = newdesc[3] #string if type == 2: charlist = (ct.c_char.from_address(adress+i) for i in range(shape)) return "".join((i.value for i in charlist)) #integer if type == 4: return ct.c_int.from_address(adress).value #arb-price int if type == 64: return ct.c_int.from_address(adress).value 

and

 class J(object): def __init__(self): self.JDll = ct.cdll.LoadLibrary(os.path.join(jDir, "j.dll")) self.JProc = self.JDll.JInit() def __call__(self, code): #Exec code, I suppose. self.JDll.JDo(self.JProc, "tmp=:"+code) return JTypes(self.deepvar("tmp"),self) 

Any help would be appreciated.

+6
source share
1 answer

Short answer: J extended precision integers are stored in base 10,000 .

More specifically: one extended integer is stored as an array of integers of machines, each in the range [0,1e4). Thus, an array of extended integers is stored as a recursive data structure . An array of extended integers is of type = 64 ("extended integer"), and its elements, each of which (a pointer to) an array, are of type = 4 ("integer").

So, conceptually (using J-notation), an array of large integers:

 123456 7890123 456789012x 

stored as a nested array of integers, each less than 10,000:

  1e4 #.^:_1&.> 123456 7890123 456789012x +-------+-------+-----------+ |12 3456|789 123|4 5678 9012| +-------+-------+-----------+ 

So, to restore the original large numbers, you will have to interpret these numbers 1 in the base of 10,000:

  10000x #.&> 12 3456 ; 789 123 ; 4 5678 9012 123456 7890123 456789012 

The only "variables of type x" in J are rational numbers, which, unsurprisingly, are stored as pairs of extended precision integers (one for the numerator, the other for the denominator). Therefore, if you have an array whose heading indicates type = 'rational' and count = 3, its data segment will have 6 elements (2 * 3). Take them in half and you have your own set of odds.

If you are trying to create a full J-Python interface, you will also have to process arrays with short and sparse ones that are similarly nested. You can learn a lot by checking binary and hexadecimal representations of J nouns using the tools built into J.

Oh, and if you're wondering, why does J store bonuses in the 10,000 base? This is because 10,000 is large enough to keep nested arrays compact, and the power-of-10 view makes it easy to format numbers in decimal format .


ยน Take care of setting the byte order (for example, 4 5678 9012 can be represented in memory as 9012 5678 4 ).

+11
source

Source: https://habr.com/ru/post/970690/


All Articles