How to resolve the algorithm Almkvist-Giullera formula for pi step by step in the AArch64 Assembly programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Almkvist-Giullera formula for pi step by step in the AArch64 Assembly programming language
Table of Contents
Problem Statement
The Almkvist-Giullera formula for calculating 1/π2 is based on the Calabi-Yau differential equations of order 4 and 5, which were originally used to describe certain manifolds in string theory.
The formula is:
This formula can be used to calculate the constant π-2, and thus to calculate π. Note that, because the product of all terms but the power of 1000 can be calculated as an integer, the terms in the series can be separated into a large integer term: multiplied by a negative integer power of 10:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Almkvist-Giullera formula for pi step by step in the AArch64 Assembly programming language
Source code in the aarch64 programming language
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program calculPi64.s */
/* this program use gmp library */
/* link with gcc option -lgmp */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ MAXI, 10
.equ SIZEBIG, 100
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessDebutPgm: .asciz "Program 64 bits start. \n"
szMessPi: .asciz "\nPI = \n"
szCarriageReturn: .asciz "\n"
szFormat: .asciz " %Zd\n"
szFormatFloat: .asciz " %.*Ff\n"
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
Result1: .skip SIZEBIG
Result2: .skip SIZEBIG
Result3: .skip SIZEBIG
Result4: .skip SIZEBIG
fIntex5: .skip SIZEBIG
fIntex6: .skip SIZEBIG
fIntex7: .skip SIZEBIG
fSum: .skip SIZEBIG
fSum1: .skip SIZEBIG
sBuffer: .skip SIZEBIG
fEpsilon: .skip SIZEBIG
fPrec: .skip SIZEBIG
fPI: .skip SIZEBIG
fTEN: .skip SIZEBIG
fONE: .skip SIZEBIG
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessDebutPgm
bl affichageMess
mov x20,#0 // loop indice
1:
mov x0,x20
bl computeAlmkvist // compute
mov x1,x0
ldr x0,qAdrszFormat // print big integer
bl __gmp_printf
add x20,x20,#1
cmp x20,#MAXI
blt 1b // and loop
mov x0,#560 // float précision in bits
bl __gmpf_set_default_prec
mov x19,#0 // compute indice
ldr x0,qAdrfSum // init to zéro
bl __gmpf_init
ldr x0,qAdrfSum1 // init to zéro
bl __gmpf_init
ldr x0,qAdrfONE // result address
mov x1,#1 // init à 1
bl __gmpf_init_set_ui
ldr x0,qAdrfIntex5 // init to zéro
bl __gmpf_init
ldr x0,qAdrfIntex6 // init to zéro
bl __gmpf_init
ldr x0,qAdrfIntex7 // init to zéro
bl __gmpf_init
ldr x0,qAdrfEpsilon // init to zéro
bl __gmpf_init
ldr x0,qAdrfPrec // init to zéro
bl __gmpf_init
ldr x0,qAdrfPI // init to zéro
bl __gmpf_init
ldr x0,qAdrfTEN
mov x1,#10 // init to 10
bl __gmpf_init_set_ui
ldr x0,qAdrfIntex6 // compute 10 pow 70
ldr x1,qAdrfTEN
mov x2,#70
bl __gmpf_pow_ui
ldr x0,qAdrfEpsilon // divide 1 by 10 pow 70
ldr x1,qAdrfONE // dividende
ldr x2,qAdrfIntex6 // divisor
bl __gmpf_div
2: // PI compute loop
mov x0,x19
bl computeAlmkvist
mov x20,x0
mov x1,#6
mul x2,x1,x19
add x6,x2,#3 // compute 6n + 3
ldr x0,qAdrfIntex6 // compute 10 pow (6n+3)
ldr x1,qAdrfTEN
mov x2,x6
bl __gmpf_pow_ui
ldr x0,qAdrfIntex7 // compute 1 / 10 pow (6n+3)
ldr x1,qAdrfONE // dividende
ldr x2,qAdrfIntex6 // divisor
bl __gmpf_div
ldr x0,qAdrfIntex6 // result big float
mov x1,x20 // big integer Almkvist
bl __gmpf_set_z // conversion in big float
ldr x0,qAdrfIntex5 // result Almkvist * 1 / 10 pow (6n+3)
ldr x1,qAdrfIntex7 // operator 1
ldr x2,qAdrfIntex6 // operator 2
bl __gmpf_mul
ldr x0,qAdrfSum1 // terms addition
ldr x1,qAdrfSum
ldr x2,qAdrfIntex5
bl __gmpf_add
ldr x0,qAdrfSum // copy terms
ldr x1,qAdrfSum1
bl __gmpf_set
ldr x0,qAdrfIntex7 // compute 1 / sum
ldr x1,qAdrfONE // dividende
ldr x2,qAdrfSum // divisor
bl __gmpf_div
ldr x0,qAdrfPI // compute square root (1 / sum )
ldr x1,qAdrfIntex7
bl __gmpf_sqrt
ldr x0,qAdrfIntex6 // compute variation PI
ldr x1,qAdrfPrec
ldr x2,qAdrfPI
bl __gmpf_sub
ldr x0,qAdrfIntex6 // absolue value
ldr x1,qAdrfIntex5
bl __gmpf_abs
add x19,x19,#1 // increment indice
ldr x0,qAdrfPrec // copy PI -> prévious
ldr x1,qAdrfPI
bl __gmpf_set
ldr x0,qAdrfIntex6 // compare gap and epsilon
ldr x1,qAdrfEpsilon
bl __gmpf_cmp
cmp w0,#0 // !!! cmp return result on 32 bits
bgt 2b // if gap is highter -> loop
ldr x0,qAdrszMessPi // title display
bl affichageMess
ldr x2,qAdrfPI // PI display
ldr x0,qAdrszFormatFloat
mov x1,#70
bl __gmp_printf
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc #0 // perform the system call
qAdrszMessDebutPgm: .quad szMessDebutPgm
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrfIntex5: .quad fIntex5
qAdrfIntex6: .quad fIntex6
qAdrfIntex7: .quad fIntex7
qAdrfSum: .quad fSum
qAdrfSum1: .quad fSum1
qAdrszFormatFloat: .quad szFormatFloat
qAdrszMessPi: .quad szMessPi
qAdrfEpsilon: .quad fEpsilon
qAdrfPrec: .quad fPrec
qAdrfPI: .quad fPI
qAdrfTEN: .quad fTEN
qAdrfONE: .quad fONE
/***************************************************/
/* compute almkvist_giullera formula */
/***************************************************/
/* x0 contains the number */
computeAlmkvist:
stp x19,lr,[sp,-16]! // save registers
mov x19,x0
mov x1,#6
mul x0,x1,x0
ldr x1,qAdrResult1 // result address
bl computeFactorielle // compute (n*6)!
mov x1,#532
mul x2,x19,x19
mul x2,x1,x2
mov x1,#126
mul x3,x19,x1
add x2,x2,x3
add x2,x2,#9
lsl x2,x2,#5 // * 32
ldr x0,qAdrResult2 // result
ldr x1,qAdrResult1 // operator
bl __gmpz_mul_ui
mov x0,x19
ldr x1,qAdrResult1
bl computeFactorielle
ldr x0,qAdrResult3
bl __gmpz_init // init to 0
ldr x0,qAdrResult3 // result
ldr x1,qAdrResult1 // operator
mov x2,#6
bl __gmpz_pow_ui
ldr x0,qAdrResult1 // result
ldr x1,qAdrResult3 // operator
mov x2,#3
bl __gmpz_mul_ui
ldr x0,qAdrResult3 // result
ldr x1,qAdrResult2 // operator
ldr x2,qAdrResult1 // operator
bl __gmpz_cdiv_q
ldr x0,qAdrResult3 // return result address
100:
ldp x19,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrszFormat: .quad szFormat
qAdrResult1: .quad Result1
qAdrResult2: .quad Result2
qAdrResult3: .quad Result3
/***************************************************/
/* compute factorielle N */
/***************************************************/
/* x0 contains the number */
/* x1 contains big number result address */
computeFactorielle:
stp x19,lr,[sp,-16]! // save registers
stp x20,x21,[sp,-16]! // save registers
mov x19,x0 // save N
mov x20,x1 // save result address
mov x0,x1 // result address
mov x1,#1 // init to 1
bl __gmpz_init_set_ui
ldr x0,qAdrResult4
bl __gmpz_init // init to 0
mov x21,#1
1: // loop
ldr x0,qAdrResult4 // result
mov x1,x20 // operator 1
mov x2,x21 // operator 2
bl __gmpz_mul_ui
mov x0,x20 // copy result4 -> result
ldr x1,qAdrResult4
bl __gmpz_set
add x21,x21,#1 // increment indice
cmp x21,x19 // N ?
ble 1b // no -> loop
ldr x0,qAdrResult4
ldp x20,x21,[sp],16 // restaur 2 registers
ldp x19,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrResult4: .quad Result4
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
You may also check:How to resolve the algorithm Tonelli-Shanks algorithm step by step in the Julia programming language
You may also check:How to resolve the algorithm Sequence of non-squares step by step in the Oforth programming language
You may also check:How to resolve the algorithm Burrows–Wheeler transform step by step in the Seed7 programming language
You may also check:How to resolve the algorithm Tau function step by step in the Factor programming language
You may also check:How to resolve the algorithm Here document step by step in the Go programming language