我试图计算泰勒系列
1 + x + x 2 / 2! + x 3 / 3! + ... + x 10 / 10!。
我的程序每次都给我无限,我是MIPS的新手。我只关注0到10之间的输入,包括0和10。当 n = 10时,我们停在 x n / n!我想出了什么:
# A program to first, find the power of x^n and the factorial of n. x,n are both between 0-10 inclusive. Then it finds the taylor series
.data
pr1: .asciiz "Enter Float x: "
.text
.globl main
main:
la $a0, pr1 # prompt user for x
li $v0,4 # print string
syscall
li $v0, 6 # read single
syscall
mtc1 $v0, $f0 # f0 <--- x
exponent: # f0 --> x
mul.s $f1, $f0, $f0 # f1 --> x^2
mul.s $f2, $f1, $f0 # f2 --> x^3
mul.s $f3, $f2, $f0 # f3 --> x^4
mul.s $f4, $f3, $f0 # f4 --> x^5
mul.s $f5, $f4, $f0 # f5 --> x^6
mul.s $f6, $f5, $f0 # f6 --> x^7
mul.s $f7, $f6, $f0 # f7 --> x^8
mul.s $f8, $f7, $f0 # f8 --> x^9
mul.s $f9, $f8, $f0 # f9 --> x^10
factorial:
li $s0, 1 # n = 10
li $t0, 1
add $t0, $t0, $s0 # t0 = 2! = 2
add $t1, $t0, $s0 # t1 = 3
mul $t1, $t1, $t0 # t1 = 3! = 6
add $t2, $t0, $t0 # t2 = 4
mul $t2, $t2, $t1 # t2 = 4! = 24
addi $t3, $t1, -1 # t3 = 5
mul $t3, $t3, $t2 # t3 = 5! = 120
add $t4, $t1, $zero # t4 = 6
mul $t4, $t4, $t3 # t4 = 6! = 720
addi $t5, $t1, 1 # t5 = 7
mul $t5, $t5, $t4 # t5 = 7! = 5040
add $t6, $t1, $t0 # t6 = 8
mul $t6, $t6, $t5 # t6 = 8! = 40320
add $t7, $t1, $t0
addi $t7, $t7, 1 # t7 = 9
mul $t7, $t7, $t6 # t7 = 9! = 362880
mul $s1, $t0, 5 # s1 = 10
mul $s1, $s1, $t7 # s1 = 10! = 3628800
taylor:
mtc1 $s0, $f10 # $f10 = 1
cvt.s.w $f10, $f10 # convert to float
add.s $f0, $f0, $f10 # = 1 + x
mtc1 $t0, $f10 # move n! to cp1
cvt.s.w $f10, $f10 # convert to float
div.s $f10, $f10, $f1 # divide x^n/ n
add.s $f0, $f0, $f10 # = 1 + x + x^2/2!
mtc1 $t1, $f10 # move n! to cp1
cvt.s.w $f10, $f10 # convert to float
div.s $f10, $f10, $f2 # divide x^n/ n
add.s $f0, $f0, $f10 # = 1 + x +.. + x^3/3!
mtc1 $t2, $f10 # move n! to cp1
cvt.s.w $f10, $f10 # convert to float
div.s $f10, $f10, $f3 # divide x^n/ n
add.s $f0, $f0, $f10 # = 1 + x +..+ x^4/4!
mtc1 $t3, $f10 # move n! to cp1
cvt.s.w $f10, $f10 # convert to float
div.s $f10, $f10, $f4 # divide x^n/ n
add.s $f0, $f0, $f10 # = 1 + x + x^5/5!
mtc1 $t4, $f10 # move n! to cp1
cvt.s.w $f10, $f10 # convert to float
div.s $f10, $f10, $f5 # divide x^n/ n
add.s $f0, $f0, $f10 # = 1 + x + x^6/6!
mtc1 $t5, $f10 # move n! to cp1
cvt.s.w $f10, $f10 # convert to float
div.s $f10, $f10, $f6 # divide x^n/ n
add.s $f0, $f0, $f10 # = 1 + x + x^7/7!
mtc1 $t6, $f10 # move n! to cp1
cvt.s.w $f10, $f10 # convert to float
div.s $f10, $f10, $f7 # divide x^n/ n
add.s $f0, $f0, $f10 # = 1 + x + x^8/8!
mtc1 $t7, $f10 # move n! to cp1
cvt.s.w $f10, $f10 # convert to float
div.s $f10, $f10, $f8 # divide x^n/ n
add.s $f0, $f0, $f10 # = 1 + x + x^9/9!
mtc1 $s1, $f10 # move n! to cp1
cvt.s.w $f10, $f10 # convert to float
div.s $f10, $f10, $f9 # divide x^n/ n
add.s $f0, $f0, $f10 # = 1 + x + x^10/10!
end:
mov.s $f12, $f0 # argument
li $v0, 2 # print float
syscall
li $v0, 10
syscall
答案 0 :(得分:2)
首先,你有一些错误:
(1)正如Jester所说,你的“读浮动”系统调用有一个错误。
(2)您正在计算factorial(n)
但泰勒余弦系列使用factorial(2n)
,因此它会更快地增加。
(3)您可能遇到的另一个问题是[ 使用正确的阶乘],即您使用整数数学作为阶乘。当计算到10次迭代时,阶乘将溢出32位整数。对于10次迭代,我们最终得到[至少] factorial(18)
,这是~6.4e15(即不适合32整数)。对于整数数学,只要值包含32位,因子而不是稳定地增加,将“振荡”。
我的方法略有不同。
我创建了一个使用循环的解决方案,而不是预先计算所有内容[正如您所做的那样]。这可能会或可能不会帮助您调试自己的实现,但如果我不建议重构,我会失职。
下面是循环实现的asm代码。还有一个我用来调试算法的C版本。还有一个带有一些调试语句的asm版本。
<强>理由:强>
您正尝试使用泰勒级数求和/扩展计算cos
[至10次迭代]。毕竟,公式 使用“求和”运算符。
您要预先计算所有x^n
项和所有阶乘项,并将它们放在不同的寄存器中。这很好,因为MIPS有32个FP寄存器。但是,使用双精度,我们必须使用两个寄存器,因此这意味着只有16个数字。在某种程度上,你所做的是相当于编译器“循环展开”。
另一个问题是很难跟踪所有这些寄存器。什么是什么价值。
并且,假设问题是使用20次迭代而不是10次。我们可能会用完寄存器。在实践中,这对于其他系列扩展可能是必要的,因为我们可能不会很快收敛。
所以,我建议使用一个循环。每个功率项都可以从前一个计算出来。同样,对于每个阶乘。
使用循环方法的另一个好处是,我们可以监控术语值[cur
](越来越小),并且如果它的变化小于a,则不是使用固定数量的迭代。一定数量[或小于该数量](例如,对于双精度,1e-14)我们可以停止,因为我们的值不会比我们的浮点格式[和硬件]为我们提供的精度更好。
注意:这是不,如下所示,但很容易实现。
这是asm版本。注释中使用的变量名称是指C代码中使用的变量名称[后面跟随]。
# A program to calculate cos(x) using taylor series
.data
pr1: .asciiz "Enter Float x: "
sym_fnc: .asciiz "cos(x): "
nl: .asciiz "\n"
.text
.globl main
main:
li $s7,0 # clear debug flag #+
# prompt user for x value
li $v0,4 # print string
la $a0,pr1 # prompt user for x
syscall
# read user's x value
li $v0,6 # read float
syscall
jal qcos
la $a0,sym_fnc # string
jal prtflt
li $v0,10
syscall
# qcos -- calculate cosine
#
# RETURNS:
# f0 -- cos(x)
#
# arguments:
# f0 -- x value
#
# registers:
# f2 -- x value
# f4 -- sum
# f6 -- xpow (x^n)
# f8 -- n2m1
# f10 -- factorial (nfac)
# f12 -- RESERVED (used in pflt)
# f14 -- current term
# f16 -- x^2
#
# f18 -- a one value
#
# t0 -- zero value
# t1 -- one value
#
# t6 -- negation flag
# t7 -- iteration count
qcos:
move $s0,$ra # save return address
mov.s $f2,$f0 # save x value
mul.s $f16,$f2,$f2 # get x^2
li $t0,0 # get a zero
li $t1,1 # get a one
li $t6,1 # start with positive term
# xpow = 1
mtc1 $t1,$f6 # xpow = 1
cvt.s.w $f6,$f6 # convert to float
# n2m1 = 0
mtc1 $t0,$f8 # n2m1 = 0
cvt.s.w $f8,$f8 # convert to float
# nfac = 1
mtc1 $t1,$f10 # nfac = 1
cvt.s.w $f10,$f10 # convert to float
# get a one value
mtc1 $t1,$f18 # onetmp = 1
cvt.s.w $f18,$f18 # convert to float
# zero the sum
mtc1 $t0,$f4 # sum = 0
cvt.s.w $f4,$f4 # convert to float
li $t7,10 # set number of iterations
cosloop:
div.s $f14,$f6,$f10 # cur = xpow / nfac
# apply the term to the sum
bgtz $t6,cospos # do positive? yes, fly
sub.s $f4,$f4,$f14 # subtract the term
b cosneg
cospos:
add.s $f4,$f4,$f14 # add the term
cosneg:
subi $t7,$t7,1 # bump down iteration count
blez $t7,cosdone # are we done? if yes, fly
# now calculate intermediate values for _next_ term
# get _next_ power term
mul.s $f6,$f6,$f16 # xpow *= x2
# go from factorial(2n) to factorial(2n+1)
add.s $f8,$f8,$f18 # n2m1 += 1
mul.s $f10,$f10,$f8 # nfac *= n2m1
# go from factorial(2n+1) to factorial(2n+1+1)
add.s $f8,$f8,$f18 # n2m1 += 1
mul.s $f10,$f10,$f8 # nfac *= n2m1
neg $t6,$t6 # flip sign for next time
j cosloop
cosdone:
mov.s $f0,$f4 # set return value
move $ra,$s0 # restore return address
jr $ra
# dbgflt -- debug print float number
dbgflt:
bnez $s7,prtflt
jr $ra
# dbgnum -- debug print int number
dbgnum:
beqz $s7,dbgnumdone
li $v0,1
syscall
dbgnumdone:
jr $ra
# dbgprt -- debug print float number
dbgprt:
beqz $s7,dbgprtdone
li $v0,4
syscall
dbgprtdone:
jr $ra
# prtflt -- print float number
#
# arguments:
# a0 -- prefix string (symbol name)
# f12 -- number to print
prtflt:
li $v0,4 # syscall: print string
syscall
li $v0,2 # print float
syscall
li $v0,4 # syscall: print string
la $a0,nl # print newline
syscall
jr $ra
这是C代码[它还包含sin(x)
的代码]:
// mipsqsin/mipstaylor -- fast sine/cosine calculation
#include <stdio.h>
#include <math.h>
#define ITERMAX 10
// qcos -- calculate cosine
double
qcos(double x)
{
int iteridx;
double x2;
double cur;
int neg;
double xpow;
double n2m1;
double nfac;
double sum;
// square of x
x2 = x * x;
// values for initial terms where n==0:
xpow = 1.0;
n2m1 = 0.0;
nfac = 1.0;
neg = 1;
sum = 0.0;
iteridx = 0;
// NOTES:
// (1) with the setup above, we can just use the loop without any special
// casing
while (1) {
// calculate current value
cur = xpow / nfac;
// apply it to sum
if (neg < 0)
sum -= cur;
else
sum += cur;
// bug out when done
if (++iteridx >= ITERMAX)
break;
// now calculate intermediate values for _next_ sum term
// get _next_ power term
xpow *= x2;
// go from factorial(2n) to factorial(2n+1)
n2m1 += 1.0;
nfac *= n2m1;
// now get factorial(2n+1+1)
n2m1 += 1.0;
nfac *= n2m1;
// flip sign
neg = -neg;
}
return sum;
}
// qsin -- calculate sine
double
qsin(double x)
{
int iteridx;
double x2;
double cur;
int neg;
double xpow;
double n2m1;
double nfac;
double sum;
// square of x
x2 = x * x;
// values for initial terms where n==0:
xpow = x;
n2m1 = 1.0;
nfac = 1.0;
neg = 1;
sum = 0.0;
iteridx = 0;
// NOTES:
// (1) with the setup above, we can just use the loop without any special
// casing
while (1) {
// calculate current value
cur = xpow / nfac;
// apply it to sum
if (neg < 0)
sum -= cur;
else
sum += cur;
// bug out when done
if (++iteridx >= ITERMAX)
break;
// now calculate intermediate values for _next_ sum term
// get _next_ power term
xpow *= x2;
// go from factorial(2n+1) to factorial(2n+1+1)
n2m1 += 1.0;
nfac *= n2m1;
// now get factorial(2n+1+1+1)
n2m1 += 1.0;
nfac *= n2m1;
// flip sign
neg = -neg;
}
return sum;
}
// testfnc -- test function
void
testfnc(int typ,const char *sym)
{
double (*efnc)(double);
double (*qfnc)(double);
double vale;
double valq;
double x;
double dif;
int iter;
switch (typ) {
case 0:
efnc = cos;
qfnc = qcos;
break;
case 1:
efnc = sin;
qfnc = qsin;
break;
default:
efnc = NULL;
qfnc = NULL;
break;
}
iter = 0;
for (x = 0.0; x <= M_PI_2; x += 0.001, ++iter) {
vale = efnc(x);
valq = qfnc(x);
dif = vale - valq;
dif = fabs(dif);
printf("%s: %d x=%.15f e=%.15f q=%.15f dif=%.15f %s\n",
sym,iter,x,vale,valq,dif,(dif < 1e-14) ? "PASS" : "FAIL");
}
}
// main -- main program
int
main(int argc,char **argv)
{
testfnc(0,"cos");
testfnc(1,"sin");
return 0;
}
这是我使用的调试语句的asm版本。这是“printf调试”,就像在C中一样。
或者,mars
和spim
模拟器都内置了GUI调试功能。您可以通过单击单个按钮单步执行代码。您可以看到所有寄存器值的实时显示。
注意:我个人更喜欢mars
。这适用于mars
,但我不知道spim
是否支持.eqv
伪操作。
# A program to calculate cos(x) using taylor series
.data
pr1: .asciiz "Enter Float x: "
sym_fnc: .asciiz "cos(x): "
nl: .asciiz "\n"
#+ddef f2,x
.eqv fpr_x $f2 #+
sym_x: .asciiz "x[f2]: " #+
#+
#+ddef f16,x2
.eqv fpr_x2 $f16 #+
sym_x2: .asciiz "x2[f16]: " #+
#+
#+ddef f4,sum
.eqv fpr_sum $f4 #+
sym_sum: .asciiz "sum[f4]: " #+
#+
#+ddef f6,xpow
.eqv fpr_xpow $f6 #+
sym_xpow: .asciiz "xpow[f6]: " #+
#+
#+ddef f8,n2m1
.eqv fpr_n2m1 $f8 #+
sym_n2m1: .asciiz "n2m1[f8]: " #+
#+
#+ddef f10,nfac
.eqv fpr_nfac $f10 #+
sym_nfac: .asciiz "nfac[f10]: " #+
#+
#+ddef f14,cur
.eqv fpr_cur $f14 #+
sym_cur: .asciiz "cur[f14]: " #+
#+
.text
.globl main
main:
#+dask
la $a0,dbgask # prompt user #+
li $v0,4 # print string #+
syscall #+
# get debug flag #+
li $v0,5 #+
syscall #+
move $s7,$v0 #+
.data #+
dbgask: .asciiz "Debug (0/1) ? " #+
.text #+
#+
# prompt user for x value
li $v0,4 # print string
la $a0,pr1 # prompt user for x
syscall
# read user's x value
li $v0,6 # read float
syscall
jal qcos
la $a0,sym_fnc # string
jal prtflt
li $v0,10
syscall
# qcos -- calculate cosine
#
# RETURNS:
# f0 -- cos(x)
#
# arguments:
# f0 -- x value
#
# registers:
# f2 -- x value
# f4 -- sum
# f6 -- xpow (x^n)
# f8 -- n2m1
# f10 -- factorial (nfac)
# f12 -- RESERVED (used in pflt)
# f14 -- current term
# f16 -- x^2
#
# f18 -- a one value
#
# t0 -- zero value
# t1 -- one value
#
# t6 -- negation flag
# t7 -- iteration count
qcos:
move $s0,$ra # save return address
mov.s $f2,$f0 # save x value
#+dflt x
la $a0,sym_x #+
mov.s $f12,fpr_x #+
jal dbgflt #+
#+
mul.s $f16,$f2,$f2 # get x^2
#+dflt x2
la $a0,sym_x2 #+
mov.s $f12,fpr_x2 #+
jal dbgflt #+
#+
li $t0,0 # get a zero
li $t1,1 # get a one
li $t6,1 # start with positive term
# xpow = 1
mtc1 $t1,$f6 # xpow = 1
cvt.s.w $f6,$f6 # convert to float
# n2m1 = 0
mtc1 $t0,$f8 # n2m1 = 0
cvt.s.w $f8,$f8 # convert to float
# nfac = 1
mtc1 $t1,$f10 # nfac = 1
cvt.s.w $f10,$f10 # convert to float
# get a one value
mtc1 $t1,$f18 # onetmp = 1
cvt.s.w $f18,$f18 # convert to float
# zero the sum
mtc1 $t0,$f4 # sum = 0
cvt.s.w $f4,$f4 # convert to float
li $t7,10 # set number of iterations
cosloop:
#+dprt "cosloop: LOOP iter="
la $a0,dprt_1 #+
jal dbgprt #+
.data #+
dprt_1: .asciiz "cosloop: LOOP iter=" #+
.text #+
#+
#+dnum $t7
move $a0,$t7 #+
jal dbgnum #+
#+
#+dprt "\n"
la $a0,dprt_2 #+
jal dbgprt #+
.data #+
dprt_2: .asciiz "\n" #+
.text #+
#+
#+dflt xpow
la $a0,sym_xpow #+
mov.s $f12,fpr_xpow #+
jal dbgflt #+
#+
#+dflt nfac
la $a0,sym_nfac #+
mov.s $f12,fpr_nfac #+
jal dbgflt #+
#+
div.s $f14,$f6,$f10 # cur = xpow / nfac
#+dflt cur
la $a0,sym_cur #+
mov.s $f12,fpr_cur #+
jal dbgflt #+
#+
# apply the term to the sum
bgtz $t6,cospos # do positive? yes, fly
#+dprt "costerm: NEG\n"
la $a0,dprt_3 #+
jal dbgprt #+
.data #+
dprt_3: .asciiz "costerm: NEG\n" #+
.text #+
#+
sub.s $f4,$f4,$f14 # subtract the term
b cosneg
cospos:
#+dprt "costerm: POS\n"
la $a0,dprt_4 #+
jal dbgprt #+
.data #+
dprt_4: .asciiz "costerm: POS\n" #+
.text #+
#+
add.s $f4,$f4,$f14 # add the term
cosneg:
#+dflt sum
la $a0,sym_sum #+
mov.s $f12,fpr_sum #+
jal dbgflt #+
#+
subi $t7,$t7,1 # bump down iteration count
blez $t7,cosdone # are we done? if yes, fly
# now calculate intermediate values for _next_ term
#+dprt "cosloop: CALC\n"
la $a0,dprt_5 #+
jal dbgprt #+
.data #+
dprt_5: .asciiz "cosloop: CALC\n" #+
.text #+
#+
# get _next_ power term
mul.s $f6,$f6,$f16 # xpow *= x2
# go from factorial(2n) to factorial(2n+1)
add.s $f8,$f8,$f18 # n2m1 += 1
#+dflt n2m1
la $a0,sym_n2m1 #+
mov.s $f12,fpr_n2m1 #+
jal dbgflt #+
#+
mul.s $f10,$f10,$f8 # nfac *= n2m1
#+dflt nfac
la $a0,sym_nfac #+
mov.s $f12,fpr_nfac #+
jal dbgflt #+
#+
# go from factorial(2n+1) to factorial(2n+1+1)
add.s $f8,$f8,$f18 # n2m1 += 1
#+dflt n2m1
la $a0,sym_n2m1 #+
mov.s $f12,fpr_n2m1 #+
jal dbgflt #+
#+
mul.s $f10,$f10,$f8 # nfac *= n2m1
#+dflt nfac
la $a0,sym_nfac #+
mov.s $f12,fpr_nfac #+
jal dbgflt #+
#+
neg $t6,$t6 # flip sign for next time
j cosloop
cosdone:
mov.s $f0,$f4 # set return value
move $ra,$s0 # restore return address
jr $ra
# dbgflt -- debug print float number
dbgflt:
bnez $s7,prtflt
jr $ra
# dbgnum -- debug print int number
dbgnum:
beqz $s7,dbgnumdone
li $v0,1
syscall
dbgnumdone:
jr $ra
# dbgprt -- debug print float number
dbgprt:
beqz $s7,dbgprtdone
li $v0,4
syscall
dbgprtdone:
jr $ra
# prtflt -- print float number
#
# arguments:
# a0 -- prefix string (symbol name)
# f12 -- number to print
prtflt:
li $v0,4 # syscall: print string
syscall
li $v0,2 # print float
syscall
li $v0,4 # syscall: print string
la $a0,nl # print newline
syscall
jr $ra
以下是单个值的调试输出日志:
Debug (0/1) ? 1
Enter Float x: 0.123
x[f2]: 0.123
x2[f16]: 0.015129001
cosloop: LOOP iter=10
xpow[f6]: 1.0
nfac[f10]: 1.0
cur[f14]: 1.0
costerm: POS
sum[f4]: 1.0
cosloop: CALC
n2m1[f8]: 1.0
nfac[f10]: 1.0
n2m1[f8]: 2.0
nfac[f10]: 2.0
cosloop: LOOP iter=9
xpow[f6]: 0.015129001
nfac[f10]: 2.0
cur[f14]: 0.0075645004
costerm: NEG
sum[f4]: 0.9924355
cosloop: CALC
n2m1[f8]: 3.0
nfac[f10]: 6.0
n2m1[f8]: 4.0
nfac[f10]: 24.0
cosloop: LOOP iter=8
xpow[f6]: 2.2888667E-4
nfac[f10]: 24.0
cur[f14]: 9.536944E-6
costerm: POS
sum[f4]: 0.99244505
cosloop: CALC
n2m1[f8]: 5.0
nfac[f10]: 120.0
n2m1[f8]: 6.0
nfac[f10]: 720.0
cosloop: LOOP iter=7
xpow[f6]: 3.4628265E-6
nfac[f10]: 720.0
cur[f14]: 4.8094813E-9
costerm: NEG
sum[f4]: 0.99244505
cosloop: CALC
n2m1[f8]: 7.0
nfac[f10]: 5040.0
n2m1[f8]: 8.0
nfac[f10]: 40320.0
cosloop: LOOP iter=6
xpow[f6]: 5.2389105E-8
nfac[f10]: 40320.0
cur[f14]: 1.2993329E-12
costerm: POS
sum[f4]: 0.99244505
cosloop: CALC
n2m1[f8]: 9.0
nfac[f10]: 362880.0
n2m1[f8]: 10.0
nfac[f10]: 3628800.0
cosloop: LOOP iter=5
xpow[f6]: 7.925948E-10
nfac[f10]: 3628800.0
cur[f14]: 2.1841789E-16
costerm: NEG
sum[f4]: 0.99244505
cosloop: CALC
n2m1[f8]: 11.0
nfac[f10]: 3.99168E7
n2m1[f8]: 12.0
nfac[f10]: 4.790016E8
cosloop: LOOP iter=4
xpow[f6]: 1.1991168E-11
nfac[f10]: 4.790016E8
cur[f14]: 2.503367E-20
costerm: POS
sum[f4]: 0.99244505
cosloop: CALC
n2m1[f8]: 13.0
nfac[f10]: 6.2270208E9
n2m1[f8]: 14.0
nfac[f10]: 8.7178289E10
cosloop: LOOP iter=3
xpow[f6]: 1.8141439E-13
nfac[f10]: 8.7178289E10
cur[f14]: 2.0809583E-24
costerm: NEG
sum[f4]: 0.99244505
cosloop: CALC
n2m1[f8]: 15.0
nfac[f10]: 1.30767428E12
n2m1[f8]: 16.0
nfac[f10]: 2.09227885E13
cosloop: LOOP iter=2
xpow[f6]: 2.7446184E-15
nfac[f10]: 2.09227885E13
cur[f14]: 1.3117842E-28
costerm: POS
sum[f4]: 0.99244505
cosloop: CALC
n2m1[f8]: 17.0
nfac[f10]: 3.55687415E14
n2m1[f8]: 18.0
nfac[f10]: 6.4023735E15
cosloop: LOOP iter=1
xpow[f6]: 4.1523335E-17
nfac[f10]: 6.4023735E15
cur[f14]: 6.485616E-33
costerm: NEG
sum[f4]: 0.99244505
cos(x): 0.99244505
-- program is finished running --