Now that we’ve implemented the easy way to compute π, I’ll let you work in groups to compute it faster, using a different approximation series:
$$\pi = 3 + \sum_{i=0}^\infty (-1)^i \frac{4}{(2i + 2) (2i+3) (2i+4)}
= 3 + \frac{4}{2 \times 3 \times 4} - \frac{4}{4 \times 5 \times 6} + \cdots$$
This series converges much faster than the traditional one: while the traditional series takes nearly 500,00 iterations to get just five digits of precision, this series gets there in about 12. Here’s a skeleton program for you:
section .data
zero: dq 0.0
one: dq 1.0
two: dq 2.0
four: dq 4.0
negone: dq -1.0
limit: dq 0.000001
format: db "%f", 10, 0
section .text
extern printf
global main
main:
push rbp
mov rbp, rsp
;; Compute pi
movsd xmm0, qword [limit]
call compute_pi
; Return value in xmm0
;; Print result
mov rdi, format
mov al, 1
call printf
mov rax, 0
pop rbp
ret
compute_pi:
push rbp
mov rbp, rsp
; xmm0 = Approximation limit
; Return result in xmm0
; YOUR CODE HERE
pop rbp
ret
You can find a copy of this file on the server in /usr/local/class/src/pi.s
.
Note that I’ve changed all the constants to qwords
(i.e., double
s), so
don’t forget to use the double-precision versions of the various operations.
It should be possible to change the limit
in the .text
section to get more
(or less) precise approximations.