我在Python中编写了一些J绑定(https://gist.github.com/Synthetica9/73def2ec09d6ac491c98)。但是,我遇到了处理任意精度整数的问题:输出没有任何意义。每次都会有所不同(但总体规模相同)。相关的代码:
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
和
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)
任何帮助都会被贬低。
答案 0 :(得分:11)
简答: J的扩展精度整数存储在base 10,000 中。
更具体地说:单个扩展整数存储为机器整数数组,每个整数在[0,1e4]范围内。因此,扩展整数数组存储为recursive data structure。扩展整数数组的类型为= 64(“扩展整数”),其元素(每个元素本身(指向)一个数组)的类型= 4(“整数”)。
因此,从概念上(使用J表示法),大整数数组:
123456 7890123 456789012x
存储为机器整数的嵌套数组,每个都小于10,000:
1e4 #.^:_1&.> 123456 7890123 456789012x
+-------+-------+-----------+
|12 3456|789 123|4 5678 9012|
+-------+-------+-----------+
因此,要恢复原始的大数字,你必须解释基数10,000中的这些数字¹:
10000x #.&> 12 3456 ; 789 123 ; 4 5678 9012
123456 7890123 456789012
J中唯一的其他“x型变量”是有理数,毫不奇怪,它们被存储为扩展精度整数对(一个用于分子,另一个用于分母)。因此,如果您的数组的标题指示type ='rational'且count = 3,则其数据段将具有6个元素(2 * 3)。成对地采取这些,你有你的比例数组。
如果您正在尝试构建完整的J-Python接口,那么您还必须处理类似嵌套的盒装和稀疏数组。通过使用tools built in to J检查J名词的二进制和十六进制表示,您可以学到很多东西。
哦,如果你想知道为什么J存储基数10,000的bignums?这是因为10,000足以保持嵌套数组的紧凑性,以及10次幂表示makes it easy to format numbers in decimal。
¹请注意调整字节顺序(例如,4 5678 9012
可在内存中表示为9012 5678 4
)。