CKKS Estimated Precision based on the Input Range

Hi all. I am trying to understand how the estimated precision is affected when the number of ciphertext levels is exhausted due to repeated multiplications. In the following setting:

#include "openfhe.h"

using namespace std;
using namespace lbcrypto;

int main() {
    int batchsize = 8;
    int scaling_mod_size = 59;
    int first_scaling_mod_size = 59;
    int logN = 16;
    int depth = 20;
    int numLargeDigits = 3;
    SecretKeyDist secretKeyDist = UNIFORM_TERNARY;
    CCParams<CryptoContextCKKSRNS> parameters;
    parameters.SetSecurityLevel(HEStd_128_classic);
    parameters.SetBatchSize(batchsize);
    parameters.SetRingDim(1 << logN);
    parameters.SetScalingModSize(scaling_mod_size);
    parameters.SetFirstModSize(first_scaling_mod_size);
    parameters.SetMultiplicativeDepth(depth);
    parameters.SetNumLargeDigits(numLargeDigits);
    parameters.SetSecretKeyDist(secretKeyDist);

    CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
    cc->Enable(PKE);
    cc->Enable(ADVANCEDSHE);
    cc->Enable(LEVELEDSHE);
    cc->Enable(KEYSWITCH);

    auto keys= cc->KeyGen();
    cc->EvalMultKeyGen(keys.secretKey);

    // Experiment: What is the estimated precision after repeated multiplications
    vector<double> x1 = {1, 2, 3, 4, 1, 2, 3, 4};
    vector<double> x2 = {1, 2, 1, 2, 1, 2, 1, 2};

    Plaintext pt1 = cc->MakeCKKSPackedPlaintext(x1);
    Plaintext pt2 = cc->MakeCKKSPackedPlaintext(x2);

    auto ct1 = cc->Encrypt(keys.publicKey, pt1);
    auto ct2 = cc->Encrypt(keys.publicKey, pt2);

    auto cMul = cc->EvalMult(ct1, ct2);
    for (int i=0; i<depth-1; i++){
        cMul = cc->EvalMult(cMul, ct2);
    }

    Plaintext pMul;
    cc->Decrypt(keys.secretKey, cMul, &pMul);
    pMul->SetLength(batchsize);

    cout << "Repeated HEMult result: "  << endl << pMul << endl;

    // The same experiment, using a smaller range for the plaintext values
    vector<double> x1_small = {0.5, 0.3, -0.2, 0.7, -0.7, 0.6, -0.1, 0.1};
    vector<double> x2_small = {0.9, 0.1, 0.2, 0.05, -0.2, -0.1, -0.7, 0.3};

    Plaintext pt1_small = cc->MakeCKKSPackedPlaintext(x1_small);
    Plaintext pt2_small = cc->MakeCKKSPackedPlaintext(x2_small);

    auto ct1_small = cc->Encrypt(keys.publicKey, pt1_small);
    auto ct2_small = cc->Encrypt(keys.publicKey, pt2_small);

    auto cMul_small = cc->EvalMult(ct1_small, ct2_small);
    for (int i=0; i<depth-1; i++){
        cMul_small = cc->EvalMult(cMul_small, ct2_small);
    }

    Plaintext pMul_small;
    cc->Decrypt(keys.secretKey, cMul_small, &pMul_small);
    pMul_small->SetLength(batchsize);

    cout << "Repeated HEMult result, smaller range inputs: " << endl << pMul_small << endl;

    return 0;
}

with the output:

Repeated HEMult result: 
(-0.482971, -0.0339079, 0.219426, 0.297126, -0.482971, -0.0339078, 0.219426, 0.297126,  ... ); Estimated precision: 27 bits

Repeated HEMult result, smaller range inputs: 
(0.0607883, -3.02942e-16, -1.63923e-15, -3.43574e-17, -7.52176e-15, 1.32031e-16, -7.97923e-05, 3.48671e-12,  ... ); Estimated precision: 51 bits

The estimated precision dropped severely when the input range is larger. In the error analyses in the “Approximate Homomorphic Encryption with Reduced Approximation Error” paper, I do not see any error terms taking into account the input range. Could you please help me with this?