1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_cos_q15.c
4  * Description:  Fast cosine calculation for Q15 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 
arm_divide_q15(q15_t numerator,q15_t denominator,q15_t * quotient,int16_t * shift)60 arm_status arm_divide_q15(q15_t numerator,
61   q15_t denominator,
62   q15_t *quotient,
63   int16_t *shift)
64 {
65   int16_t sign=0;
66   q31_t temp;
67   int16_t shiftForNormalizing;
68 
69   *shift = 0;
70 
71   sign = (numerator>>15) ^ (denominator>>15);
72 
73   if (denominator == 0)
74   {
75      if (sign)
76      {
77         *quotient = 0x8000;
78      }
79      else
80      {
81         *quotient = 0x7FFF;
82      }
83      return(ARM_MATH_NANINF);
84   }
85 
86   numerator = abs(numerator);
87   denominator = abs(denominator);
88 
89   temp = ((q31_t)numerator << 15) / ((q31_t)denominator);
90 
91   shiftForNormalizing= 17 - __CLZ(temp);
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=temp;
104 
105   return(ARM_MATH_SUCCESS);
106 }
107 
108 /**
109   @} end of divide group
110  */
111