简体   繁体   中英

16-Bit addition of 2n Scaled Integer

When I going to implement 16-Bit addition of 2n Scaled Integer from autosar specification. I didn't get what is a, b and c values in these.

I am going to implement 16-Bit addition of 2n Scaled Integer from autosar specification for mfx modules. in which I get in 8.6.4.1 16-Bit Addition of 2n Scaled Integer in which they specify a Radix point position of the first fixed point operand. Must be a constant expression. b Radix point position of the second fixed point operand. Must be a constant expression. c Radix point position of the fixed point result. Must be a constant expression.

Valid range: 0 ≤ |a - b| ≤ 15
(c - b) ≤ 15, (a - c) ≤ 15, a ≥ b
(c - a) ≤ 15, (b - c) ≤ 15, a < b

But I don't understand How will I get the range value for c.

for below condition

 #include "stdio.h"
  void main()
  {
    if(a > =b)
    C = 2^(c-a) * [x + (y * 2^(a-b))]
    else

    C = 2^(c-b) * [(x * 2^(b-a)) + y].
  }

What will be the ans if x =10, y=10, and a=20, b=10, and c= 100;

It seems you have a problem converting a maths equation to C source code. Please note that in maths, 2^n means raise 2 to the power n. Thus m*2^n means m*2^abs(n) if n >=0, and means m/(2^abs(n)) if n < 0.

Thus, reading the spec, page 53-54 , we have for example:

#include <stdint.h>

uint16_t Mfx_AddP2_u16u16_u16(uint16_t x, uint16_t y, int16_t a, int16_t b, int16_t c)
{
    if(a>=b)
    {
        if(((a-b)>15) || ((c-b)>15) || ((a-c)>15))
        {
          //SWS_Mfx_00154 - saturate to boundary value
          return UINT16_MAX;
        }
        else
        {
            uint32_t baseValue = (UINT32_C(1) << (a-b)) * y + x;
            if(c>=a)
            {
                return (uint16_t)(baseValue << (c-a));
            }
            else
            {
                //SWS_Mfx_00155 - round to zero
                return (uint16_t)(baseValue >> (a-c));
            }
        }
    }
    else
    {
        if(((b-a)>15) || ((c-a)>15) || ((b-c)>15))
        {
          //SWS_Mfx_00154 - saturate to boundary value
          return UINT16_MAX;
        }
        else
        {
            uint32_t baseValue = (UINT32_C(1) << (b-a)) * x + y;
            if(c>=b)
            {
                return (uint16_t)(baseValue << (c-b));
            }
            else
            {
                //SWS_Mfx_00155 - round to zero
                return (uint16_t)(baseValue >> (b-c));
            }
        }
    }
}

I trust you can similarly complete the functions declared below:

uint16_t Mfx_AddP2_u16s16_u16(uint16_t x,  int16_t y, int16_t a, int16_t b, int16_t c);
uint16_t Mfx_AddP2_s16s16_u16( int16_t x,  int16_t y, int16_t a, int16_t b, int16_t c);
int16_t  Mfx_AddP2_u16u16_s16(uint16_t x, uint16_t y, int16_t a, int16_t b, int16_t c);
int16_t  Mfx_AddP2_u16s16_s16(uint16_t x,  int16_t y, int16_t a, int16_t b, int16_t c);
int16_t  Mfx_AddP2_s16s16_s16( int16_t x,  int16_t y, int16_t a, int16_t b, int16_t c);

Note: be careful of signed parameters and return values.


Edit: Answering actual question

Given you ask what the result will be when x =10, y=10, and a=20, b=10, and c= 100; Check:

  1. Is 0<=abs(ab)<=15 - yes
  2. Is a>=b - yes
  3. Is (cb)<=15 - NO

So, in terms of SWS_Mfx_00154, the result must be

  1. UINT16_MAX (65535) for Mfx_AddP2_u16u16_u16, Mfx_AddP2_u16s16_u16 and Mfx_AddP2_s16s16_u16

, and

  1. INT16_MAX (32767) for Mfx_AddP2_u16u16_s16, Mfx_AddP2_u16s16_s16 and Mfx_AddP2_s16s16_s16

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM