Why is the frequency response different based on the amplitude of the impulse I feed into the filter? I am working on a 2-pole IIR high-pass filter.  The filter is fixed point and it is causing me some issues.  I believe I'm just misunderstanding something.  I am implementing everything in Octave for now, but eventually it will be implemented in a 32-bit processor.  The corner frequency is very low, $2.7\textrm{ Hz}$.

When I test the filter by passing in an impulse and then doing an fft on the output, I get different results based on the magnitude of the impulse.

First, I made the filter using signed 64-bit integers just for testing.  So the impulse I feed into the filter looks like this:

Fs = 51200; %sample frequency
impulse = int64( [2^31, zeros(1,Fs*10-1)] ); %multiply by 10 to get 0.1 Hz resolution


Here is the fixed-point impulse response compared against the floating-point impulse response.



If I rerun the code but with a larger impulse I get the desired frequency response.

Fs = 51200; %sample frequency
impulse = int64( [2^63, zeros(1,Fs*10-1)] ); %multiply by 10 to get 0.1 Hz resolution




They match so closely you can barely see the red, floating-point response.


Why is there this difference just from changing the amplitude of the input?
I need to implement this in 32 bits, but when I do, the amplitude of the input is restricted to $2^{31}$ so I end up with the distorted impulse response.  How can I fix this or work around this?
The lower amplitude the input signal has compared to the resolution of the filter coefficients the weaker is its ability to shape the frequency of the input signal. It also depends on the span of the filter coefficients.

You get the same result if you feed the filter with 32-bit coefficients with a signal having an amplitude covering only the lower 16-bits. If you want to work around this effect you need to amplify the input signal.