+ Post New Thread
Results 1 to 17 of 17
  1. #1
    Member level 2
    Points: 331, Level: 3

    Join Date
    Apr 2019
    Posts
    49
    Helped
    0 / 0
    Points
    331
    Level
    3

    fixed point arithmetic in c

    I am looking for a C code to perform Q15 addition, subtraction, multiplication, division , sine(x) and cosine(x). Can anybody provide good reference that works?

  2. #2
    Advanced Member level 3
    Points: 6,259, Level: 18

    Join Date
    Feb 2014
    Posts
    901
    Helped
    296 / 296
    Points
    6,259
    Level
    18

    Re: fixed point arithmetic in c

    I'd start with searching "fixed point [add/subtract/mult]" etc. There are different options for each. Saying its fixed point also doesn't tell us if you have hardware multiply/divide support though I'll assume no.


    Understand that a lot of it comes down to designing your algorithms around the limitations. For example if you don't have hardware multiply then plan around doing power of 2 shift divides with << and >>. Sin and cos are typically implemented with a look-up-table.



    •   AltAdvertisement

        
       

  3. #3
    Advanced Member level 1
    Points: 5,642, Level: 17

    Join Date
    May 2005
    Posts
    460
    Helped
    105 / 105
    Points
    5,642
    Level
    17

    Re: fixed point arithmetic in c

    short a, b, c;
    Addition: c = a + b;
    Subtraction: c = a - b;
    Multiplication: c = (short)((a * (long)b) >> 15);



  4. #4
    Member level 2
    Points: 331, Level: 3

    Join Date
    Apr 2019
    Posts
    49
    Helped
    0 / 0
    Points
    331
    Level
    3

    Re: fixed point arithmetic in c

    how to take care of oveflow for addition and subtraction? c should be short or long?
    Last edited by curious_mind; 25th October 2019 at 10:24. Reason: additional info



  5. #5
    Advanced Member level 1
    Points: 5,642, Level: 17

    Join Date
    May 2005
    Posts
    460
    Helped
    105 / 105
    Points
    5,642
    Level
    17

    Re: fixed point arithmetic in c

    Quote Originally Posted by curious_mind View Post
    how to take care of oveflow for addition and subtraction? c should be short or long?
    You'd need to use long - or an MCU that supports saturating fixed-point types.



  6. #6
    Member level 2
    Points: 331, Level: 3

    Join Date
    Apr 2019
    Posts
    49
    Helped
    0 / 0
    Points
    331
    Level
    3

    Re: fixed point arithmetic in c

    Hi

    I am considering 2's complement unsigned data that varies from 0 to 65535. What would happen if I would add 10 with 32767. The result is a negative number. How would I guard this?



  7. #7
    Super Moderator
    Points: 261,937, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,781
    Helped
    13913 / 13913
    Points
    261,937
    Level
    100

    Re: fixed point arithmetic in c

    Your specification is rather shallow. You say "take care of overflow". How? Saturate? Generate an exception?

    In case, additional code is required. The CPU may be already able to detect a signed integer overflow. Or you detect it by monitoring the arguments and result signs.



  8. #8
    Member level 2
    Points: 331, Level: 3

    Join Date
    Apr 2019
    Posts
    49
    Helped
    0 / 0
    Points
    331
    Level
    3

    Re: fixed point arithmetic in c

    I came up with the following custom c code. Your view on this will be helpful
    Code:
    unsigned int add (unsigned int a ,unsigned  int b)
    {
    unsigned int res;
    unsigned long tmp;
    tmp=a+b;
    if((a<=32767) && (b<=32767))   // both numbers are positive
    {
     if (tmp>32767)
    {
     res=32767;
    }
    }
    
    else if((a>32767) && (b>32767))  // both numbers are negative
    {
     if (tmp>32768)
    {
     res=32768;
    }
    }
    else
    {
    res=tmp & 0xffff;
    }
    return(res);
    }
    
    unsigned int sub (unsigned int a ,unsigned  int b)
    {
    unsigned int res;
    unsigned long tmp;
    
    if((a<=32767) && ( b>=32768) || (a>=32768) && (b<=32767))
    {
      if(a>b)
    {
    res=32768;
    }
    else
    {
    res=32767;
    }
    }
    else
    {
    tmp=a-b;
    res=tmp & 0xffff;
    }
    
    return(res);
    }
    Last edited by betwixt; 27th October 2019 at 10:24. Reason: added code tags



    •   AltAdvertisement

        
       

  9. #9
    Super Moderator
    Points: 261,937, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,781
    Helped
    13913 / 13913
    Points
    261,937
    Level
    100

    Re: fixed point arithmetic in c

    Looks O.K. as a demonstration but can be coded more efficiently using bit operations.



  10. #10
    Member level 2
    Points: 331, Level: 3

    Join Date
    Apr 2019
    Posts
    49
    Helped
    0 / 0
    Points
    331
    Level
    3

    Re: fixed point arithmetic in c

    Stuck with basics operations again in Q1.15 multiplication. What should be the result of multiplication of 23166 (0.707) and 65535 (0.0), the result is 46332 and not 65535. Could it be clarified? It is very basic question



  11. #11
    Super Moderator
    Points: 261,937, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,781
    Helped
    13913 / 13913
    Points
    261,937
    Level
    100

    Re: fixed point arithmetic in c

    Apparently you don't scale the multiply result correctly.



  12. #12
    Member level 2
    Points: 331, Level: 3

    Join Date
    Apr 2019
    Posts
    49
    Helped
    0 / 0
    Points
    331
    Level
    3

    Re: fixed point arithmetic in c

    I used the following code

    a=23166, b=65535;

    long result,a,b;

    result =(a*b)>>15;



  13. #13
    Super Moderator
    Points: 261,937, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,781
    Helped
    13913 / 13913
    Points
    261,937
    Level
    100

    Re: fixed point arithmetic in c

    b=65535 is outside Q1.15 (int16) range. Should be -1.



  14. #14
    Member level 2
    Points: 331, Level: 3

    Join Date
    Apr 2019
    Posts
    49
    Helped
    0 / 0
    Points
    331
    Level
    3

    Re: fixed point arithmetic in c

    Q1.15 range is -1.0 to +1.0 , -32768 to 32767, in hex it is 0x8000-0xffff for negative range and 0x0000-0x7fff for positive range, so 65535 is around -1. So I guess it is the valid range.



    •   AltAdvertisement

        
       

  15. #15
    Advanced Member level 4
    Points: 7,598, Level: 20
    Achievements:
    7 years registered

    Join Date
    Jul 2010
    Location
    Sweden
    Posts
    1,019
    Helped
    387 / 387
    Points
    7,598
    Level
    20

    Re: fixed point arithmetic in c

    The two's complement format is good for addition/subtraction, but bad for multiplication/division.
    You want to multiply Q1.15 values 23166 (0.707) with 65535 (-0.0003)
    The simplest solution is to separate the sign calculation from the magnitude calculation.
    You multiply a positive value with a negative value, so the result will be negative.
    For the magnitude calculation, convert the negative value 65535 to the corresponding positive value 1.
    Multiply 23166 with 1 => 23166.
    Shift down 15 bits => 0
    With rounding before shift, the result will be 1.
    We then remember that the result should be negative, so we convert 1 to 65535.



  16. #16
    Super Moderator
    Points: 261,937, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,781
    Helped
    13913 / 13913
    Points
    261,937
    Level
    100

    Re: fixed point arithmetic in c

    so 65535 is around -1
    Not when represented with long data type as in post #12.



  17. #17
    Member level 2
    Points: 331, Level: 3

    Join Date
    Apr 2019
    Posts
    49
    Helped
    0 / 0
    Points
    331
    Level
    3

    Re: fixed point arithmetic in c

    fixed point multiplication issue is resolved. Thanks for all help



--[[ ]]--