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 */