It’s difficult to say something definite about the issue you are running into without some minimum working example, but here are some things to keep in mind.
The ciphertext (I assume you are working with CKKS) encrypts a vector of N/2 length, which is natively the size of the slots, for N the ring dimension. The operations over ciphertexts are always applied over this length, regardless of the set batch size or number of slots. In some cases, particularly in bootstrapping, knowing that your message vector is actually smaller than N/2 can improve efficiency by a lot (we can run smaller dimension FFTs). When setting a smaller number of slots, we are working in a smaller subring (see Background of https://eprint.iacr.org/2018/1043.pdf). Internally, using sparse packing for n < N/2 slots means your n message slots of interest are cloned for N/(2n) times.
If you start with a ciphertext with full packing (N/2 slots) and want to move to a sparser packing (n < N/2) because only the first n values are non-zero, you have to do this change manually, i.e., apply rotations and additions. Note that if the values after n are not already zero, you have to apply multiplicative masking to zero them out. SetSlots
only sets a parameter, telling the library how to interpret the current ciphertext. This is why you see a scaling difference: your ciphertext is still the same, but you apply decryption with a smaller number of slots. See these discussions in the forum for more explanations: OpenFHE SetSlots method: what is the usage scenario? , How does CKKS Sparse Encoding work exactly? , How to transform a ciphertext from one slot count to another without decryption.
Also, we work with power of two slots. Is int numSlots = 14;
referring to the number of slots being 2^{14}?