1/* 2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16export class MathCordic { 17 static readonly AG_CONST : double = 0.6072529350; 18 static readonly TARGET_ANGLE : double = 28.027; 19 static readonly expected : double = 10362.570468755888; 20 static readonly ANGLES : double[] = [MathCordic.fnFixed(45.0), MathCordic.fnFixed(26.565), MathCordic.fnFixed(14.0362), MathCordic.fnFixed(7.12502), MathCordic.fnFixed(3.57633), MathCordic.fnFixed(1.78991), MathCordic.fnFixed(0.895174), MathCordic.fnFixed(0.447614), MathCordic.fnFixed(0.223811), MathCordic.fnFixed(0.111906), MathCordic.fnFixed(0.055953), MathCordic.fnFixed(0.027977)]; 21 22 static fnFixed(x : double): double { 23 return x * 65536.0; 24 } 25 26 static fnFloat(x : double): double { 27 return x / 65536.0; 28 } 29 30 static fnDegToRad(x : double): double { 31 return 0.017453 * x; 32 } 33 34 static cordicsincos(target : double): double { 35 let x : double; 36 let y : double; 37 let targetAngle : double = MathCordic.fnFixed(target); 38 let currAngle : double = 0; 39 let step : int ; 40 x = MathCordic.fnFixed(MathCordic.AG_CONST * cos(0)); 41 y = sin(0); 42 for (step = 0; step < 12; step++) { 43 let newX : double ; 44 if (targetAngle > currAngle) { 45 newX = x - (y as int >> step); 46 y = (x as int >> step) + y; 47 x = newX; 48 currAngle += MathCordic.ANGLES[step]; 49 } 50 else { 51 newX = x + (y as int >> step); 52 y = -(x as int >> step) + y; 53 x = newX; 54 currAngle -= MathCordic.ANGLES[step]; 55 } 56 } 57 return MathCordic.fnFloat(x) * MathCordic.fnFloat(y); 58 } 59 60 static cordic(runs : int): double { 61 let total : double = 0; 62 for (let i : int = 0; i < runs; i++) { 63 total += MathCordic.cordicsincos(MathCordic.TARGET_ANGLE); 64 } 65 return total; 66 } 67 68 n : int; 69 70 public run(): void { 71 this.n = 25000; 72 let total : double = MathCordic.cordic(this.n); 73 74 assert total == MathCordic.expected: "Incorrect result"; 75 } 76} 77 78function main(): void { 79 let a = new MathCordic; 80 a.run(); 81} 82 83