Issue:
cistring should use int64 everywhere

Partly a question. Why does `fci.cistring` use `int32` in some places instead of `int64` everywhere? For example, `make_strings` returns a list of `int64`, but `gen_occslst` and `gen_linkstr_index` return arrays of `int32`. I think using `int64` everywhere would be more consistent and support more use cases.

Fix patch:
diff --git a/pyscf/fci/cistring.py b/pyscf/fci/cistring.py
index 983178ff54..0ef463d693 100644
--- a/pyscf/fci/cistring.py
+++ b/pyscf/fci/cistring.py
@@ -343,12 +343,13 @@ def addr2str(norb, nelec, addr):
     '''Convert CI determinant address to string'''
     if norb >= 64:
         raise NotImplementedError('norb >= 64')
-    assert num_strings(norb, nelec) > addr
+    max_addr = num_strings(norb, nelec)
+    assert max_addr > addr
 
-    if addr < 2**31:
+    if max_addr < 2**31:
         return addrs2str(norb, nelec, [addr])[0]
-
-    return _addr2str(norb, nelec, addr)
+    else:
+        return _addr2str(norb, nelec, addr)
 
 def _addr2str(norb, nelec, addr):
     if addr == 0 or nelec == norb or nelec == 0:


Test patch:
diff --git a/pyscf/fci/test/test_cistring.py b/pyscf/fci/test/test_cistring.py
index 634d92a7cd..dcd5d6f988 100644
--- a/pyscf/fci/test/test_cistring.py
+++ b/pyscf/fci/test/test_cistring.py
@@ -156,6 +156,12 @@ def test_addr2str(self):
         self.assertEqual(bin(cistring.addr2str(6, 3, 8)), '0b11010')
         self.assertEqual(bin(cistring.addr2str(7, 4, 9)), '0b110011')
 
+        # Test large addresss
+        string = 0b101101111101101111001110111111110111111100
+        address = cistring.str2addr(norb=63, nelec=32, string=string)
+        string2 = cistring.addr2str(norb=63, nelec=32, addr=address)
+        self.assertEqual(string, string2)
+
     def test_str2addr(self):
         self.assertEqual(str2addr(6, 3, int('0b11001' ,2)), cistring.str2addr(6, 3, int('0b11001' ,2)))
         self.assertEqual(str2addr(6, 3, int('0b11010' ,2)), cistring.str2addr(6, 3, int('0b11010' ,2)))