This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to add Q format numbers in the source code

This has to be easy but I've looked in the compiler manual and I can't find a way to do this.

I just want to be able to have Q format numbers in the C code. I've seen this as 1.23Q14 or 0.978!15 and then it does the multiplication for you as 1.23 * 2^14 and puts it in an INT or LONG.

 

Right now I'm doing source code as 1.23*Q14 with #define Q14 16384. But all that is FLOAT for the computation and I think it's actually doing that computation in real time rather than only doing that computation at compile time. 

  • Hi DLR,

    What processor are you using?

    If it is a fixed point processor (probably), it will emulate floating point numbers and it will not be able to make this calculation in compile time.

    If you want to figure out how much is 0.25 in Q14 and do 0.25*16384 -> you are emulating floating point math and that takes a lot of cycles. So as you know hoe much it is, you would need to use the value 4096 directly, and not try to calculate.

    You would need to use shifts and Q format math, depending on the processor you are using there are come IQ math libraries:

    http://processors.wiki.ti.com/index.php/Software_libraries

     

    What I mean by not using float, is for example:

    Q14 number <- (Q14 number)*(Q14 number)>>14

    For example, if you want to multiply 0.5 with 0.5 (or a variable) you do:

    8192 * 8192 >> 14 = 4096  => (0.25)  in Q14

  • I'm using a 5515 and porting code from a 6713. In the 6713 it has been converted to use only FIXED point math and now it needs to be moved to the 5515.

    The IQmath library does not look too bad but it says it just runs on the 64x parts.

    I know what your saying about using "4096" directly as the value of interest. I was thinking I saw the feature before it was in a DSP assembler. With an AT&T DSP assembler I could say 1.23!14  for Q14 and it would do the computation at compile time and I thought older TI assemblers would do 1.23Q14 and do that computation at compile time (Or I guess at assembly time since it's the assembler and not the compiler). But it would sure be nice if I could say 1.23Q14 in the 5515 C compiler and have the compiler convert it to an Int32 or Int16 at compile time so I don't need to compute fixed constants by hand. 

  • I moved your post to the Compiler forum, let's see if there are any more inputs on this.

     

  • The TI compiler tools offer no special syntax for specifying Q format numbers in either C code or assembly code.

    Thanks and regards,

    -George

     

  • DLR said:

    Right now I'm doing source code as 1.23*Q14 with #define Q14 16384. But all that is FLOAT for the computation and I think it's actually doing that computation in real time rather than only doing that computation at compile time. 

    The compiler can completely evaluate compile-time constant expressions involving floating-point numbers at compilation time, so if you are using literal constants, you should not be seeing any run-time floating-point operations.  In some cases, you may need to use the optimizer, at least at level -o0.  Could you provide a test case (including command-line options used) where the compiler uses run-time floating-point operations for your constant * Q14 operation?

  • The basis for the statement that it was doing it in real time was that I would build it as:

    a = _smpy( b , QQ14*0.1234  );

    and I would look at the MAP file and the size of the memory used.

    Then I would build the code set as:

    a = _smpy( b , 20218 );

    and the memory used in the MAP file would be less so my logical conclusion was that it was doing the multiply in real time as it had a bigger code size.

    The what has me stumped this morning is I do the above and the memory used in the MAP file is the same in both cases so it seems OK now. I tried this a few weeks ago and I'm sure I would get a different size for the MAP file based on the 2 different implementations above. So I don't know if I cast stuff different before or what. But now I don't see a difference.

    Your complier always seems pretty smart so I expected it to multiply it out at compile time.

    So lets call this answered for now and I'll see if I can figure out how I was doing it before where it was 2 different sized for the MAP file.

     

  • You should probably look look at the disassembly (either in the CCS disassembly window, or by using the command-line dis6x) to see what instructions the compiler generates for this line of code.  If there is a function call there, it's surely a floating-point emulation helper function.

  • I went and looked at the dis-assembly and the compiler is just way beyond smart.

    I would do:

    _smpy(1234 , (QQ15*0.1234))

    and all it would do is load a word because it was smart enough to know that even with the _smpy every thing was constant.

    Then I put in a variable and it did the same load of a constant because the compiler was smart enough to know that the variable had not changed because the variable was set at the start of the function.

    So once I finally tricked the compiler, that's smarter than me, into thinking something was changing it would in fact multiply out the constant values and not do a run time call.

    So before when I saw a different size in the map file I must have been wrong or I was doing a different form. I think what is likely is I was doing a form where the compiler was making it very simple and then I would change it to where the compiler had to actually do a computation and I perceived that as computation in real time but it was the compiler expanding it per the above conditions where it was no longer a simple load of a constant.