# I have 24-bit data in two's complement 32-bit integers. I need Q31 data

I have been trying to learn about Q31 format (as well as Q15), but I am having trouble understanding how it works.

So my CODEC is giving me 24-bit two's complement data. I have converted this data successfully to 32-bit two's complement data and back. I would like to so some math on this data using Q31 format. For starters, hopefully something like attenuation. I am using a PIC32MZ series processor. Here is some of the code I am working with.

#define Q31 int
#define Q63 long long

Q31 Q31multQ31 (Q31 a, Q31 b){
Q63 y;
y = (Q63) a * (Q63) b;
y >> 31;
return ((Q31) y);
}

// Super basic attenuation (hopefully)
left_output =  Q31multQ31(left_input,0b00000000001111111111111111111111);


This seems to give me awful noise. left_input and left_output are int (signed 32-bit). Is there some sort of conversion I am missing to use these as Q31?

• Does Q31 mean that that there are 32 bits in total and that the number is between $-1$ (represented by 0x80000000) inclusive and $1-2^{-31}$ (represented by 0x7fffffff) inclusive? – Olli Niemitalo Nov 9 '16 at 7:38
• @OlliNiemitalo yes, thats the goal. Is the data I have already usable in that way? or do I have to do some form of conversion? – BBales Nov 9 '16 at 15:42
• Your code seems fine. There could be an unhandled overflow in Q31multQ31 if you multiplied 0x8000000 by itself, but that's not your problem here. How do you do the conversions? – Olli Niemitalo Nov 9 '16 at 16:44
• Looks like a bug: you want y >>= 31; You are missing the "=" sign.The line as written doesn't do anything. – Hilmar Nov 9 '16 at 19:27
• @Hilmar Yes! Missed that. You could write it as an answer so that BBales can accept it. – Olli Niemitalo Nov 12 '16 at 7:57