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