Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

In QTSPIM Many applications in mathematics involve computing various values of t

ID: 3689434 • Letter: I

Question

In QTSPIM

Many applications in mathematics involve computing various values of the sin function. It can be proven that

sin(x) = x – x 3 /3! + x5 /5! - x 7 /7! + …

for all radian values of x. It is important to remember that x must be expressed in radians, not degrees ( radians = 180 degrees). Of course, this is an infinite sum, so we can’t hope to actually add all of these values up! The good news is that the later terms get so small that a partial sum can provide a very nice approximation for the value of sin(x).

You are to write a double precision function (result returned in $f0) called sin with one double precision parameter (in $f12), along with a little driver program for testing your function. Your function should use the summation formula as an approximation for the value of sin(x), using the following guide for terminating the summation:

If the absolute value of the next term is less than 1.0e-15, then terminate the summation (and don’t even bother to add in that next term).

Even though the summation is valid for all values of x, there is a problem with convergence when you use values of x having absolute values greater than 30 or so. You may assume that we will test your program with values within this range.

Here is a sample execution of my code:

Let's test our sin function!

Enter a (radian) value for x (or 999 to exit): 0

Our approximation for sin(0) is 0

Enter a (radian) value for x (or 999 to exit): 1

Our approximation for sin(1) is 0.8414709848078965

Enter a (radian) value for x (or 999 to exit): 10

Our approximation for sin(10) is -0.54402111088906224

Enter a (radian) value for x (or 999 to exit): -10

Our approximation for sin(-10) is 0.54402111088906224

Enter a (radian) value for x (or 999 to exit): 1.570796326794896 [/2]

Our approximation for sin(1.5707963267948959) is 1

Enter a (radian) value for x (or 999 to exit): -.5232

Our approximation for sin(-0.5232) is -0.49965461045512305

Enter a (radian) value for x (or 999 to exit): -.5235987755982988 [-/6]

Our approximation for sin(-0.52359877559829882) is -0.5

Enter a (radian) value for x (or 999 to exit): 999

Come back soon!

Explanation / Answer

sin:
   addi    $sp, $sp, -4   # adjust stack for $ra
   sw   $ra, 0($sp)   # save the return address to stack
  

   addi   $s1, $zero, 1   # set $s1 (counter to 1)
   add   $s2, $zero, $zero
   mov.d   $f6, $f12
   mov.d   $f10, $f12  

loopsin:
   mov.d   $f4, $f12   # (re)set $f4 = $f0 = x
   addi   $s0, $zero, 1   # (re)set $s0 to 2
   addi   $s1, $s1, 2   # add 2 to counter


for1:   slt   $t0, $s0, $s1   #loop x^y
   beq   $t0, $zero, exit1  

   mul.d   $f4, $f4, $f12   # $f4 = $f4 x $f4
  
   addi   $s0, $s0, 1  

   j    for1


exit1:

   move   $s0, $s1   # set counter to high value
   addi   $t1, $zero, 1   # set $t1 to 1
  
   l.d   $f2, const1

for2:   slt   $t0, $s0, $t1
   bne   $t0, $zero, exit2
  
   mtc1.d   $s0, $f8
   cvt.d.w   $f8, $f8

   mul.d   $f2, $f2, $f8

   addi   $s0, $s0 -1
   j   for2
  


exit2:


  
   div.d   $f4, $f4, $f2   # $f4 = (x^y) / y!
      


   abs.d   $f8, $f4
  
   l.d   $f16, test   # exit if $f4 < 1.0e-15
   c.lt.d   $f8, $f16
   bc1t   exitsin
  

   bne   $s2, $zero, goadd # if $s2 != 0 goadd
  

   sub.d   $f6, $f6, $f4   # x = x - ((x^y) / y!)
   addi   $s2, $s2, 1   # add 1 to $s2 add next round

   j   loopsin  

goadd:
   add.d   $f6, $f6, $f4   # x = x + ((x^y) / y!)
   add   $s2, $zero, $zero   # reset $s2 to 0 sub next round
      
   j   loopsin      
  
  
  
exitsin:  

  
   mov.d   $f0, $f6
   lw   $ra, 0($sp)   # restore the return address
   addi   $sp, $sp, 4   # adjust stack pointer to pop item


   jr    $ra       # return

main:   la    $a0, intro   # output intro
   li    $v0, 4
   syscall

loop:   la    $a0, req   # output request radian
   li    $v0, 4
   syscall

   li    $v0, 7       # input value
   syscall
  
   l.d   $f16, flag   # exit if 999 was entered
   c.eq.d   $f16, $f0
   bc1t   out
  
   la   $a0, ans1   # output text part(1) of answer
   li   $v0, 4
   syscall
      
   mov.d   $f12, $f0   # move input into $f12 print and to pass to sin
   li   $v0, 3
   syscall

   la   $a0, ans2   # output text part(2) of answer
   li   $v0, 4
   syscall
  
   jal   sin       # call function sin

   mov.d   $f12, $f0   # move return $f0 into $f12 to print
   li   $v0, 3
   syscall

   j loop


out:    la $a0, bye # display closing
   li $v0, 4
   syscall
  
   li $v0, 10 # exit from the program
   syscall


   .data
intro:   .asciiz "Let's test our sin function! "
req:   .asciiz " Enter a (radian) value for x (or 999 to exit): "
ans1:   .asciiz "Our approximation for sin("  
ans2:   .asciiz ") is "
line:   .asciiz " "   
bye:   .asciiz "Come back soon!"
const1:   .double 1.0
test:   .double 0.000000000000001
flag:   .double 999.0

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote