Files
2025-02-Numerical/lib/nr/cpp/recipes/arcode.cpp
2025-09-12 18:55:25 +09:00

73 lines
1.9 KiB
C++

#include "nr.h"
namespace {
inline unsigned long JTRY(const unsigned long j, const unsigned long k,
const unsigned long m)
{
return (unsigned long) (DP(j)*DP(k)/DP (m));
}
}
void NR::arcode(unsigned long &ich, string &code, unsigned long &lcd,
const int isign, arithcode &acode)
{
int j,k;
unsigned long ihi,ja,jh,jl,m;
int NWK=acode.ilob.size();
if (isign == 0) {
acode.jdif=acode.nrad-1;
for (j=NWK-1;j>=0;j--) {
acode.iupb[j]=acode.nrad-1;
acode.ilob[j]=0;
acode.nc=j;
if (acode.jdif > acode.minint) return;
acode.jdif=(acode.jdif+1)*acode.nrad-1;
}
nrerror("NWK too small in arcode.");
} else {
if (isign > 0) {
if (ich > acode.nch) nrerror("bad ich in arcode.");
} else {
ja=(unsigned char) code[lcd]-acode.ilob[acode.nc];
for (j=acode.nc+1;j<NWK;j++) {
ja *= acode.nrad;
ja += ((unsigned char) code[lcd+j-acode.nc]-acode.ilob[j]);
}
ihi=acode.nch+1;
ich=0;
while (ihi-ich > 1) {
m=(ich+ihi)>>1;
if (ja >= JTRY(acode.jdif,acode.ncumfq[m],acode.ncum))
ich=m;
else ihi=m;
}
if (ich == acode.nch) return;
}
jh=JTRY(acode.jdif,acode.ncumfq[ich+1],acode.ncum);
jl=JTRY(acode.jdif,acode.ncumfq[ich],acode.ncum);
acode.jdif=jh-jl;
arcsum(acode.ilob,acode.iupb,jh,NWK,acode.nrad,acode.nc);
arcsum(acode.ilob,acode.ilob,jl,NWK,acode.nrad,acode.nc);
for (j=acode.nc;j<NWK;j++) {
if (ich != acode.nch && acode.iupb[j] != acode.ilob[j]) break;
if (isign > 0) code += (unsigned char)acode.ilob[j];
lcd++;
}
if (j+1 > NWK) return;
acode.nc=j;
for(j=0;acode.jdif<acode.minint;j++)
acode.jdif *= acode.nrad;
if (j > acode.nc) nrerror("NWK too small in arcode.");
if (j != 0) {
for (k=acode.nc;k<NWK;k++) {
acode.iupb[k-j]=acode.iupb[k];
acode.ilob[k-j]=acode.ilob[k];
}
}
acode.nc -= j;
for (k=NWK-j;k<NWK;k++) acode.iupb[k]=acode.ilob[k]=0;
}
return;
}