Author Topic: Leibniz-formula (for learning to deal with floating-point and output them...)  (Read 8354 times)

Offline andyz74

  • Jr. Member
  • *
  • Posts: 15
The well-known Leibniz-formula to calculate "pi" with many iterations.
Surely, there are faster ways to calculate pi, and there may be the question WHY to calculate pi, but nevertheless...
We can practice here to deal with floating-point-numbers, and we see, how we can print floating-point-numbers (with help of the printf-routine of C.

Quote
; nasm -f elf64 calculatepi1.asm -o calculatepi1.o
; gcc -no-pie -m64 calculatepi1.o -o calculatepi1

; Leibniz says : pi/4 =1/1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 .....


section .data
    var_oben  dq 1.0   ; Startwert Zaehler
    var_unten dq 1.0   ; Startwert Teiler
    var_0     dq 0.0   ; Null
    var_2     dq 2.0   ; Zwei
    var_minus1 dq -1.0  ; minus 1
    MSG_RESULT     db "pi = %0.18lf", 10, 0

section .text
   extern printf
    global main

main:
   push rbp
   mov rbp,rsp
    ; Set the number of iterations for the Leibniz formula
    mov rax, 200000

    movsd xmm2, qword [var_0]            ; xmm2 beginnt bei null und nimmt dann die Leibnizzahl als Viertel auf.

    ; Loop to calculate Pi using Leibniz formula
    leibniz_loop:
        ; Calculate next term
        movsd xmm0, qword [var_oben]
        movsd xmm1, qword [var_unten]
        divsd xmm0, xmm1
        addsd xmm2, xmm0               ; xmm2 hat das Viertel des Leibnizwertes!

        ; alternating sign
        movsd xmm3, qword[var_minus1]
        movsd xmm0, qword [var_oben]
        mulsd xmm0, xmm3
        movsd qword [var_oben], xmm0      

        ; Teiler zwei dazu...
        movsd xmm3, qword [var_unten]
        addsd xmm3, qword [var_2]
        movsd qword [var_unten], xmm3


        ; Decrement loop counter
        dec rax
        jnz leibniz_loop

    ; Multiply result by 4
 
   
    movsd xmm3, qword [var_2]
    mulsd xmm2, xmm3
    mulsd xmm2, xmm3
    movsd xmm0, xmm2


   mov      rdi, MSG_RESULT         ; set format for printf
   mov      rax,1         ; set one xmm registers
   call   printf         ; Call C function
   mov   rax,0            ; normal, no error, return value



   pop rbp
   
    mov rax, 60              ; System call number for sys_exit
    xor rdi, rdi             ; Exit code 0
    syscall


This is far from being optimized for speed or whatever.  It is written in a manner to understand easier what is going on.