Machin-like formulas   are useful for efficiently computing numerical approximations for 



π


{\displaystyle \pi }





Task

Verify the following Machin-like formulas are correct by calculating the value of tan   (right hand side) for each equation using exact arithmetic and showing they equal 1:

 





π
4


=
arctan
⁡


1
2


+
arctan
⁡


1
3




{\displaystyle {\pi \over 4}=\arctan {1 \over 2}+\arctan {1 \over 3}}

 
 





π
4


=
2
arctan
⁡


1
3


+
arctan
⁡


1
7




{\displaystyle {\pi \over 4}=2\arctan {1 \over 3}+\arctan {1 \over 7}}


 





π
4


=
4
arctan
⁡


1
5


−
arctan
⁡


1
239




{\displaystyle {\pi \over 4}=4\arctan {1 \over 5}-\arctan {1 \over 239}}


 





π
4


=
5
arctan
⁡


1
7


+
2
arctan
⁡


3
79




{\displaystyle {\pi \over 4}=5\arctan {1 \over 7}+2\arctan {3 \over 79}}


 





π
4


=
5
arctan
⁡


29
278


+
7
arctan
⁡


3
79




{\displaystyle {\pi \over 4}=5\arctan {29 \over 278}+7\arctan {3 \over 79}}


 





π
4


=
arctan
⁡


1
2


+
arctan
⁡


1
5


+
arctan
⁡


1
8




{\displaystyle {\pi \over 4}=\arctan {1 \over 2}+\arctan {1 \over 5}+\arctan {1 \over 8}}

 
 





π
4


=
4
arctan
⁡


1
5


−
arctan
⁡


1
70


+
arctan
⁡


1
99




{\displaystyle {\pi \over 4}=4\arctan {1 \over 5}-\arctan {1 \over 70}+\arctan {1 \over 99}}

 
 





π
4


=
5
arctan
⁡


1
7


+
4
arctan
⁡


1
53


+
2
arctan
⁡


1
4443




{\displaystyle {\pi \over 4}=5\arctan {1 \over 7}+4\arctan {1 \over 53}+2\arctan {1 \over 4443}}


 





π
4


=
6
arctan
⁡


1
8


+
2
arctan
⁡


1
57


+
arctan
⁡


1
239




{\displaystyle {\pi \over 4}=6\arctan {1 \over 8}+2\arctan {1 \over 57}+\arctan {1 \over 239}}


 





π
4


=
8
arctan
⁡


1
10


−
arctan
⁡


1
239


−
4
arctan
⁡


1
515




{\displaystyle {\pi \over 4}=8\arctan {1 \over 10}-\arctan {1 \over 239}-4\arctan {1 \over 515}}


 





π
4


=
12
arctan
⁡


1
18


+
8
arctan
⁡


1
57


−
5
arctan
⁡


1
239




{\displaystyle {\pi \over 4}=12\arctan {1 \over 18}+8\arctan {1 \over 57}-5\arctan {1 \over 239}}


 





π
4


=
16
arctan
⁡


1
21


+
3
arctan
⁡


1
239


+
4
arctan
⁡


3
1042




{\displaystyle {\pi \over 4}=16\arctan {1 \over 21}+3\arctan {1 \over 239}+4\arctan {3 \over 1042}}


 





π
4


=
22
arctan
⁡


1
28


+
2
arctan
⁡


1
443


−
5
arctan
⁡


1
1393


−
10
arctan
⁡


1
11018




{\displaystyle {\pi \over 4}=22\arctan {1 \over 28}+2\arctan {1 \over 443}-5\arctan {1 \over 1393}-10\arctan {1 \over 11018}}


 





π
4


=
22
arctan
⁡


1
38


+
17
arctan
⁡


7
601


+
10
arctan
⁡


7
8149




{\displaystyle {\pi \over 4}=22\arctan {1 \over 38}+17\arctan {7 \over 601}+10\arctan {7 \over 8149}}


 





π
4


=
44
arctan
⁡


1
57


+
7
arctan
⁡


1
239


−
12
arctan
⁡


1
682


+
24
arctan
⁡


1
12943




{\displaystyle {\pi \over 4}=44\arctan {1 \over 57}+7\arctan {1 \over 239}-12\arctan {1 \over 682}+24\arctan {1 \over 12943}}


 





π
4


=
88
arctan
⁡


1
172


+
51
arctan
⁡


1
239


+
32
arctan
⁡


1
682


+
44
arctan
⁡


1
5357


+
68
arctan
⁡


1
12943




{\displaystyle {\pi \over 4}=88\arctan {1 \over 172}+51\arctan {1 \over 239}+32\arctan {1 \over 682}+44\arctan {1 \over 5357}+68\arctan {1 \over 12943}}


and confirm that the following formula is incorrect by showing   tan   (right hand side)   is not   1:

 





π
4


=
88
arctan
⁡


1
172


+
51
arctan
⁡


1
239


+
32
arctan
⁡


1
682


+
44
arctan
⁡


1
5357


+
68
arctan
⁡


1
12944




{\displaystyle {\pi \over 4}=88\arctan {1 \over 172}+51\arctan {1 \over 239}+32\arctan {1 \over 682}+44\arctan {1 \over 5357}+68\arctan {1 \over 12944}}


These identities are useful in calculating the values:

 



tan
⁡
(
a
+
b
)
=



tan
⁡
(
a
)
+
tan
⁡
(
b
)


1
−
tan
⁡
(
a
)
tan
⁡
(
b
)





{\displaystyle \tan(a+b)={\tan(a)+\tan(b) \over 1-\tan(a)\tan(b)}}


 



tan
⁡

(
arctan
⁡


a
b


)

=


a
b




{\displaystyle \tan \left(\arctan {a \over b}\right)={a \over b}}


 



tan
⁡
(
−
a
)
=
−
tan
⁡
(
a
)


{\displaystyle \tan(-a)=-\tan(a)}




You can store the equations in any convenient data structure, but for extra credit parse them from human-readable text input.

Note: to formally prove the formula correct, it would have to be shown that 






−
3
p
i

4




{\displaystyle {-3pi \over 4}}

 < right hand side < 






5
p
i

4




{\displaystyle {5pi \over 4}}

 due to 



tan
⁡
(
)


{\displaystyle \tan()}

 periodicity.



' version 07-04-2018
' compile with: fbc -s console
 
#Include "gmp.bi"
 
#Define _a(Q) (@(Q)->_mp_num)  'a
#Define _b(Q) (@(Q)->_mp_den)  'b
 
Data "[1, 1, 2] [1, 1, 3]"
Data "[2, 1, 3] [1, 1, 7]"
Data "[4, 1, 5] [-1, 1, 239]"
Data "[5, 1, 7] [2, 3, 79]"
Data "[1, 1, 2] [1, 1, 5] [1, 1, 8]"
Data "[4, 1, 5] [-1, 1, 70] [1, 1, 99]"
Data "[5, 1, 7] [4, 1, 53] [2, 1, 4443]"
Data "[6, 1, 8] [2, 1, 57] [1, 1, 239]"
Data "[8, 1, 10] [-1, 1, 239] [-4, 1, 515]"
Data "[12, 1, 18] [8, 1, 57] [-5, 1, 239]"
Data "[16, 1, 21] [3, 1, 239] [4, 3, 1042]"
Data "[22, 1, 28] [2, 1, 443] [-5, 1, 1393] [-10, 1, 11018]"
Data "[22, 1, 38] [17, 7, 601] [10, 7, 8149]"
Data "[44, 1, 57] [7, 1, 239] [-12, 1, 682] [24, 1, 12943]"
Data "[88, 1, 172] [51, 1, 239] [32, 1, 682] [44, 1, 5357] [68, 1, 12943]"
Data "[88, 1, 172] [51, 1, 239] [32, 1, 682] [44, 1, 5357] [68, 1, 12944]"
Data ""
 
Sub work2do (ByRef a As LongInt, f1 As mpq_ptr)
 
    Dim As LongInt flag = -1
 
    Dim As Mpq_ptr x, y, z
    x = Allocate(Len(__mpq_struct)) : Mpq_init(x)
    y = Allocate(Len(__mpq_struct)) : Mpq_init(y)
    z = Allocate(Len(__mpq_struct)) : Mpq_init(z)
 
    Dim As Mpz_ptr temp1, temp2
    temp1 = Allocate(Len(__Mpz_struct)) : Mpz_init(temp1)
    temp2 = Allocate(Len(__Mpz_struct)) : Mpz_init(temp2)
 
    mpq_set(y, f1)
 
    While a > 0
        If (a And 1) = 1 Then
            If flag = -1 Then
                mpq_set(x, y)
                flag = 0
            Else
                Mpz_mul(temp1, _a(x), _b(y))
                Mpz_mul(temp2, _b(x), _a(y))
                Mpz_add(_a(z), temp1, temp2)
                Mpz_mul(temp1, _b(x), _b(y))
                Mpz_mul(temp2, _a(x), _a(y))
                Mpz_sub(_b(z), temp1, temp2)
                mpq_canonicalize(z)
                mpq_set(x, z)
            End If
        End If
 
        Mpz_mul(temp1, _a(y), _b(y))
        Mpz_mul(temp2, _b(y), _a(y))
        Mpz_add(_a(z), temp1, temp2)
        Mpz_mul(temp1, _b(y), _b(y))
        Mpz_mul(temp2, _a(y), _a(y))
        Mpz_sub(_b(z), temp1, temp2)
        mpq_canonicalize(z)
        mpq_set(y, z)
 
        a = a Shr 1
    Wend
 
    mpq_set(f1, x)
 
End Sub
 
' ------=< MAIN >=------
 
Dim As Mpq_ptr f1, f2, f3
f1 = Allocate(Len(__mpq_struct)) : Mpq_init(f1)
f2 = Allocate(Len(__mpq_struct)) : Mpq_init(f2)
f3 = Allocate(Len(__mpq_struct)) : Mpq_init(f3)
 
Dim As Mpz_ptr temp1, temp2
temp1 = Allocate(Len(__Mpz_struct)) : Mpz_init(temp1)
temp2 = Allocate(Len(__Mpz_struct)) : Mpz_init(temp2)
 
Dim As mpf_ptr float
float = Allocate(Len(__mpf_struct)) : Mpf_init(float)
 
Dim As LongInt m1, a1, b1, flag, t1, t2, t3, t4
Dim As String s, s1, s2, s3, sign
Dim As ZString Ptr zstr
 
Do
 
    Read s
    If s = "" Then Exit Do
    flag = -1
 
    While s <> ""
        t1 = InStr(s, "[") +1
        t2 = InStr(t1, s, ",") +1
        t3 = InStr(t2, s, ",") +1
        t4 = InStr(t3, s, "]")
        s1 = Trim(Mid(s, t1, t2 - t1 -1))
        s2 = Trim(Mid(s, t2, t3 - t2 -1))
        s3 = Trim(Mid(s, t3, t4 - t3))
        m1 = Val(s1)
        a1 = Val(s2)
        b1 = Val(s3)
 
        sign = IIf(m1 < 0, " - ", " + ")
        If m1 < 0 Then a1 = -a1 : m1 = Abs(m1)
        s = Mid(s, t4 +1)
        Print IIf(flag = 0, sign, ""); IIf(m1 = 1, "", Str(m1));
        Print "Atn("; s2; "/" ;s3; ")";
 
        If flag = -1 Then
            flag = 0
            Mpz_set_si(_a(f1), a1)
            Mpz_set_si(_b(f1), b1)
            If m1 > 1 Then work2do(m1, f1)
            Continue While
        End If
 
        Mpz_set_si(_a(f2), a1)
        Mpz_set_si(_b(f2), b1)
        If m1 > 1 Then work2do(m1, f2)
 
        Mpz_mul(temp1, _a(f1), _b(f2))
        Mpz_mul(temp2, _b(f1), _a(f2))
        Mpz_add(_a(f3), temp1, temp2)
        Mpz_mul(temp1, _b(f1), _b(f2))
        Mpz_mul(temp2, _a(f1), _a(f2))
        Mpz_sub(_b(f3), temp1, temp2)
        mpq_canonicalize(f3)
        mpq_set(f1, f3)
 
    Wend
 
    If Mpz_cmp_ui(_b(f1), 1) = 0 AndAlso Mpz_cmp(_a(f1), _b(f1)) = 0 Then
        Print " = 1"
    Else
        Mpf_set_q(float, f1)
        gmp_printf(!" = %.*Ff\n", 15, float)
    End If
 
Loop
 
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End