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   @addtogroup divide
40   @{
41  */
42 
43 /**
44   @brief         Fixed point division
45   @param[in]     numerator    Numerator
46   @param[in]     denominator  Denominator
47   @param[out]    quotient     Quotient value normalized between -1.0 and 1.0
48   @param[out]    shift        Shift left value to get the unnormalized quotient
49   @return        error status
50 
51   When dividing by 0, an error ARM_MATH_NANINF is returned. And the quotient is forced
52   to the saturated negative or positive value.
53  */
54 
arm_divide_q31(q31_t numerator,q31_t denominator,q31_t * quotient,int16_t * shift)55 arm_status arm_divide_q31(q31_t numerator,
56   q31_t denominator,
57   q31_t *quotient,
58   int16_t *shift)
59 {
60   int16_t sign=0;
61   q63_t temp;
62   int16_t shiftForNormalizing;
63 
64   *shift = 0;
65 
66   sign = (numerator>>31) ^ (denominator>>31);
67 
68   if (denominator == 0)
69   {
70      if (sign)
71      {
72         *quotient = 0x80000000;
73      }
74      else
75      {
76         *quotient = 0x7FFFFFFF;
77      }
78      return(ARM_MATH_NANINF);
79   }
80 
81   arm_abs_q31(&numerator,&numerator,1);
82   arm_abs_q31(&denominator,&denominator,1);
83 
84   temp = ((q63_t)numerator << 31) / ((q63_t)denominator);
85 
86   shiftForNormalizing= 32 - __CLZ(temp >> 31);
87   if (shiftForNormalizing > 0)
88   {
89      *shift = shiftForNormalizing;
90      temp = temp >> shiftForNormalizing;
91   }
92 
93   if (sign)
94   {
95     temp = -temp;
96   }
97 
98   *quotient=(q31_t)temp;
99 
100   return(ARM_MATH_SUCCESS);
101 }
102 
103 /**
104   @} end of divide group
105  */
106