Task: Improve cistring.addr2str for large address (issue #1886) (pyscf/pyscf#2050)

org: pyscf
repo: pyscf
pr_number: 2050
issue_title: Improve cistring.addr2str for large address (issue #1886)
resolved_issues: number: 1886
title: cistring error
body: Using `int32` for the indices causes issues when the range of indices exceeds the representable range of `int32`. For example, the following program crashes with `floating point exception (core dumped)`:
```python
from pyscf.fci import cistring

norb = 48
nelec = 24

string = 0b101100101000111111101011001001010001000100011011
address = cistring.str2addr(norb=norb, nelec=nelec, string=string)
string2 = cistring.addr2str(norb=norb, nelec=nelec, addr=address)
```
Additionally, these functions might succeed but give incorrect results. For example, this code does get to the assert statement, but that assertion fails:
```python
from pyscf.fci import cistring

string = 0b101101111101101111001110111111110111111100
address = cistring.str2addr(norb=63, nelec=32, string=string)
string2 = cistring.addr2str(norb=63, nelec=32, addr=address)
assert string == string2
```


Reference solution:
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: