/ Drivers / CMSIS / DSP / Source / FastMathFunctions / arm_divide_q31.c
arm_divide_q31.c
  1  /* ----------------------------------------------------------------------
  2   * Project:      CMSIS DSP Library
  3   * Title:        arm_cos_q31.c
  4   * Description:  Fast cosine calculation for Q31 values
  5   *
  6   * $Date:        23 April 2021
  7   * $Revision:    V1.9.0
  8   *
  9   * Target Processor: Cortex-M and Cortex-A cores
 10   * -------------------------------------------------------------------- */
 11  /*
 12   * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
 13   *
 14   * SPDX-License-Identifier: Apache-2.0
 15   *
 16   * Licensed under the Apache License, Version 2.0 (the License); you may
 17   * not use this file except in compliance with the License.
 18   * You may obtain a copy of the License at
 19   *
 20   * www.apache.org/licenses/LICENSE-2.0
 21   *
 22   * Unless required by applicable law or agreed to in writing, software
 23   * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 24   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 25   * See the License for the specific language governing permissions and
 26   * limitations under the License.
 27   */
 28  
 29  #include "dsp/fast_math_functions.h"
 30  #include "arm_common_tables.h"
 31  
 32  #include <stdlib.h>
 33  
 34  /**
 35    @ingroup groupFastMath
 36   */
 37  
 38  /**
 39    @defgroup divide Fixed point division
 40  
 41   */
 42  
 43  /**
 44    @addtogroup divide
 45    @{
 46   */
 47  
 48  /**
 49    @brief         Fixed point division
 50    @param[in]     numerator    Numerator
 51    @param[in]     denominator  Denominator
 52    @param[out]    quotient     Quotient value normalized between -1.0 and 1.0
 53    @param[out]    shift        Shift left value to get the unnormalized quotient
 54    @return        error status
 55  
 56    When dividing by 0, an error ARM_MATH_NANINF is returned. And the quotient is forced
 57    to the saturated negative or positive value.
 58   */
 59  
 60  arm_status arm_divide_q31(q31_t numerator,
 61    q31_t denominator,
 62    q31_t *quotient,
 63    int16_t *shift)
 64  {
 65    int16_t sign=0;
 66    q63_t temp;
 67    int16_t shiftForNormalizing;
 68  
 69    *shift = 0;
 70  
 71    sign = (numerator>>31) ^ (denominator>>31);
 72  
 73    if (denominator == 0)
 74    {
 75       if (sign)
 76       {
 77          *quotient = 0x80000000;
 78       }
 79       else
 80       {
 81          *quotient = 0x7FFFFFFF;
 82       }
 83       return(ARM_MATH_NANINF);
 84    }
 85  
 86    arm_abs_q31(&numerator,&numerator,1);
 87    arm_abs_q31(&denominator,&denominator,1);
 88  
 89    temp = ((q63_t)numerator << 31) / ((q63_t)denominator);
 90  
 91    shiftForNormalizing= 32 - __CLZ(temp >> 31);
 92    if (shiftForNormalizing > 0)
 93    {
 94       *shift = shiftForNormalizing;
 95       temp = temp >> shiftForNormalizing;
 96    }
 97  
 98    if (sign)
 99    {
100      temp = -temp;
101    }
102  
103    *quotient=(q31_t)temp;
104  
105    return(ARM_MATH_SUCCESS);
106  }
107  
108  /**
109    @} end of divide group
110   */