Check Machin-like formulas: Difference between revisions

m
m (→‎{{header|REXX}}: simplified the DO loop code.)
m (→‎{{header|Wren}}: Minor tidy)
 
(12 intermediate revisions by 8 users not shown)
Line 41:
 
<br><br>
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
{{libheader|GMP}}
<syntaxhighlight lang="freebasic">' 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</syntaxhighlight>
{{out}}
<pre>Atn(1/2) + Atn(1/3) = 1
2Atn(1/3) + Atn(1/7) = 1
4Atn(1/5) - Atn(1/239) = 1
5Atn(1/7) + 2Atn(3/79) = 1
Atn(1/2) + Atn(1/5) + Atn(1/8) = 1
4Atn(1/5) - Atn(1/70) + Atn(1/99) = 1
5Atn(1/7) + 4Atn(1/53) + 2Atn(1/4443) = 1
6Atn(1/8) + 2Atn(1/57) + Atn(1/239) = 1
8Atn(1/10) - Atn(1/239) - 4Atn(1/515) = 1
12Atn(1/18) + 8Atn(1/57) - 5Atn(1/239) = 1
16Atn(1/21) + 3Atn(1/239) + 4Atn(3/1042) = 1
22Atn(1/28) + 2Atn(1/443) - 5Atn(1/1393) - 10Atn(1/11018) = 1
22Atn(1/38) + 17Atn(7/601) + 10Atn(7/8149) = 1
44Atn(1/57) + 7Atn(1/239) - 12Atn(1/682) + 24Atn(1/12943) = 1
88Atn(1/172) + 51Atn(1/239) + 32Atn(1/682) + 44Atn(1/5357) + 68Atn(1/12943) = 1
88Atn(1/172) + 51Atn(1/239) + 32Atn(1/682) + 44Atn(1/5357) + 68Atn(1/12944) = 0.999999188225744</pre>
 
==={{header|Visual Basic .NET}}===
'''BigRat''' class based on the Arithmetic/Rational#C here at Rosetta Code.<br/>
The parser here allows for some flexibility in the input text. Case is ignored, and a variable number of spaces are allowed. Atan(), arctan(), atn() are all recognized as valid. If one of those three are not found, a warning will appear. The coefficient need not have a multiplication sign between it and the "arctan()". The left side of the equation must be pi / 4, otherwise a warning will appear.
<syntaxhighlight lang="vbnet">Imports System.Numerics
 
Public Class BigRat ' Big Rational Class constructed with BigIntegers
Implements IComparable
Public nu, de As BigInteger
Public Shared Zero = New BigRat(BigInteger.Zero, BigInteger.One),
One = New BigRat(BigInteger.One, BigInteger.One)
Sub New(bRat As BigRat)
nu = bRat.nu : de = bRat.de
End Sub
Sub New(n As BigInteger, d As BigInteger)
If d = BigInteger.Zero Then _
Throw (New Exception(String.Format("tried to set a BigRat with ({0}/{1})", n, d)))
Dim bi As BigInteger = BigInteger.GreatestCommonDivisor(n, d)
If bi > BigInteger.One Then n /= bi : d /= bi
If d < BigInteger.Zero Then n = -n : d = -d
nu = n : de = d
End Sub
Shared Operator -(x As BigRat) As BigRat
Return New BigRat(-x.nu, x.de)
End Operator
Shared Operator +(x As BigRat, y As BigRat)
Return New BigRat(x.nu * y.de + x.de * y.nu, x.de * y.de)
End Operator
Shared Operator -(x As BigRat, y As BigRat) As BigRat
Return x + (-y)
End Operator
Shared Operator *(x As BigRat, y As BigRat) As BigRat
Return New BigRat(x.nu * y.nu, x.de * y.de)
End Operator
Shared Operator /(x As BigRat, y As BigRat) As BigRat
Return New BigRat(x.nu * y.de, x.de * y.nu)
End Operator
Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
Dim dif As BigRat = New BigRat(nu, de) - obj
If dif.nu < BigInteger.Zero Then Return -1
If dif.nu > BigInteger.Zero Then Return 1
Return 0
End Function
Shared Operator =(x As BigRat, y As BigRat) As Boolean
Return x.CompareTo(y) = 0
End Operator
Shared Operator <>(x As BigRat, y As BigRat) As Boolean
Return x.CompareTo(y) <> 0
End Operator
Overrides Function ToString() As String
If de = BigInteger.One Then Return nu.ToString
Return String.Format("({0}/{1})", nu, de)
End Function
Shared Function Combine(a As BigRat, b As BigRat) As BigRat
Return (a + b) / (BigRat.One - (a * b))
End Function
End Class
 
Public Structure Term ' coefficent, BigRational construction for each term
Dim c As Integer, br As BigRat
Sub New(cc As Integer, bigr As BigRat)
c = cc : br = bigr
End Sub
End Structure
 
Module Module1
Function Eval(c As Integer, x As BigRat) As BigRat
If c = 1 Then Return x Else If c < 0 Then Return Eval(-c, -x)
Dim hc As Integer = c \ 2
Return BigRat.Combine(Eval(hc, x), Eval(c - hc, x))
End Function
 
Function Sum(terms As List(Of Term)) As BigRat
If terms.Count = 1 Then Return Eval(terms(0).c, terms(0).br)
Dim htc As Integer = terms.Count / 2
Return BigRat.Combine(Sum(terms.Take(htc).ToList), Sum(terms.Skip(htc).ToList))
End Function
 
Function ParseLine(ByVal s As String) As List(Of Term)
ParseLine = New List(Of Term) : Dim t As String = s.ToLower, p As Integer, x As New Term(1, BigRat.Zero)
While t.Contains(" ") : t = t.Replace(" ", "") : End While
p = t.IndexOf("pi/4=") : If p < 0 Then _
Console.WriteLine("warning: tan(left side of equation) <> 1") : ParseLine.Add(x) : Exit Function
t = t.Substring(p + 5)
For Each item As String In t.Split(")")
If item.Length > 5 Then
If (Not item.Contains("tan") OrElse item.IndexOf("a") < 0 OrElse
item.IndexOf("a") > item.IndexOf("tan")) AndAlso Not item.Contains("atn") Then
Console.WriteLine("warning: a term is mising a valid arctangent identifier on the right side of the equation: [{0})]", item)
ParseLine = New List(Of Term) : ParseLine.Add(New Term(1, BigRat.Zero)) : Exit Function
End If
x.c = 1 : x.br = New BigRat(BigRat.One)
p = item.IndexOf("/") : If p > 0 Then
x.br.de = UInt64.Parse(item.Substring(p + 1))
item = item.Substring(0, p)
p = item.IndexOf("(") : If p > 0 Then
x.br.nu = UInt64.Parse(item.Substring(p + 1))
p = item.IndexOf("a") : If p > 0 Then
Integer.TryParse(item.Substring(0, p).Replace("*", ""), x.c)
If x.c = 0 Then x.c = 1
If item.Contains("-") AndAlso x.c > 0 Then x.c = -x.c
End If
ParseLine.Add(x)
End If
End If
End If
Next
End Function
 
Sub Main(ByVal args As String())
Dim nl As String = vbLf
For Each item In ("pi/4 = ATan(1 / 2) + ATan(1/3)" & nl &
"pi/4 = 2Atan(1/3) + ATan(1/7)" & nl &
"pi/4 = 4ArcTan(1/5) - ATan(1 / 239)" & nl &
"pi/4 = 5arctan(1/7) + 2 * atan(3/79)" & nl &
"Pi/4 = 5ATan(29/278) + 7*ATan(3/79)" & nl &
"pi/4 = atn(1/2) + ATan(1/5) + ATan(1/8)" & nl &
"PI/4 = 4ATan(1/5) - Atan(1/70) + ATan(1/99)" & nl &
"pi /4 = 5*ATan(1/7) + 4 ATan(1/53) + 2ATan(1/4443)" & nl &
"pi / 4 = 6ATan(1/8) + 2arctangent(1/57) + ATan(1/239)" & nl &
"pi/ 4 = 8ATan(1/10) - ATan(1/239) - 4ATan(1/515)" & nl &
"pi/4 = 12ATan(1/18) + 8ATan(1/57) - 5ATan(1/239)" & nl &
"pi/4 = 16 * ATan(1/21) + 3ATan(1/239) + 4ATan(3/1042)" & nl &
"pi/4 = 22ATan(1/28) + 2ATan(1/443) - 5ATan(1/1393) - 10 ATan( 1 / 11018 )" & nl &
"pi/4 = 22ATan(1/38) + 17ATan(7/601) + 10ATan(7 / 8149)" & nl &
"pi/4 = 44ATan(1/57) + 7ATan(1/239) - 12ATan(1/682) + 24ATan(1/12943)" & nl &
"pi/4 = 88ATan(1/172) + 51ATan(1/239) + 32ATan(1/682) + 44ATan(1/5357) + 68ATan(1/12943)" & nl &
"pi/4 = 88ATan(1/172) + 51ATan(1/239) + 32ATan(1/682) + 44ATan(1/5357) + 68ATan(1/12944)").Split(nl)
Console.WriteLine("{0}: {1}", If(Sum(ParseLine(item)) = BigRat.One, "Pass", "Fail"), item)
Next
End Sub
End Module</syntaxhighlight>
{{out}}
<pre>Pass: pi/4 = ATan(1 / 2) + ATan(1/3)
Pass: pi/4 = 2Atan(1/3) + ATan(1/7)
Pass: pi/4 = 4ArcTan(1/5) - ATan(1 / 239)
Pass: pi/4 = 5arctan(1/7) + 2 * atan(3/79)
Pass: pi/4 = 5ATan(29/278) + 7*ATan(3/79)
Pass: pi/4 = atn(1/2) + ATan(1/5) + ATan(1/8)
Pass: pi/4 = 4ATan(1/5) - Atan(1/70) + ATan(1/99)
Pass: pi /4 = 5*ATan(1/7) + 4 ATan(1/53) + 2ATan(1/4443)
Pass: pi / 4 = 6ATan(1/8) + 2arctangent(1/57) + ATan(1/239)
Pass: pi/ 4 = 8ATan(1/10) - ATan(1/239) - 4ATan(1/515)
Pass: pi/4 = 12ATan(1/18) + 8ATan(1/57) - 5ATan(1/239)
Pass: pi/4 = 16 * ATan(1/21) + 3ATan(1/239) + 4ATan(3/1042)
Pass: pi/4 = 22ATan(1/28) + 2ATan(1/443) - 5ATan(1/1393) - 10 ATan( 1 / 11018 )
Pass: pi/4 = 22ATan(1/38) + 17ATan(7/601) + 10ATan(7 / 8149)
Pass: pi/4 = 44ATan(1/57) + 7ATan(1/239) - 12ATan(1/682) + 24ATan(1/12943)
Pass: pi/4 = 88ATan(1/172) + 51ATan(1/239) + 32ATan(1/682) + 44ATan(1/5357) + 68ATan(1/12943)
Fail: pi/4 = 88ATan(1/172) + 51ATan(1/239) + 32ATan(1/682) + 44ATan(1/5357) + 68ATan(1/12944)</pre>
 
=={{header|Clojure}}==
Clojure automatically handles ratio of numbers as fractions
{{trans|Go}}
<langsyntaxhighlight lang="lisp">(ns tanevaulator
(:gen-class))
 
Line 97 ⟶ 421:
" Display results "
(println "tan " q " = "(tans q)))
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 120 ⟶ 444:
(equals 0.9999991882257445)
</pre>
 
=={{header|D}}==
This uses the module of the Arithmetic Rational Task.
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.regex, std.conv, std.string, std.range,
arithmetic_rational;
 
Line 194 ⟶ 517:
writefln("%5s: %s", ans == 1 ? "OK" : "ERROR", eqn);
}
}</langsyntaxhighlight>
{{out}}
<pre> OK: pi/4 = arctan(1/2) + arctan(1/3)
Line 213 ⟶ 536:
OK: pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12943)
ERROR: pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944)</pre>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
(lib 'math)
(lib 'match)
Line 274 ⟶ 596:
(writeln '❌ f '➽ (reduce f) ))))
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="scheme">
 
(define machins
Line 321 ⟶ 643:
(* 44 (arctan 1/5357)) (* 68 (arctan 1/12944)))) ➽ 0.9999991882257442
 
</syntaxhighlight>
</lang>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: combinators formatting kernel locals math sequences ;
IN: rosetta-code.machin
 
Line 362 ⟶ 683:
} [ dup tans "tan %u = %u\n" printf ] each ;
 
MAIN: machin</langsyntaxhighlight>
{{out}}
<pre>
Line 394 ⟶ 715:
} = 10092...08223/10092...39711
</pre>
 
=={{header|FreeBASIC}}==
{{libheader|GMP}}
<lang freebasic>' 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</lang>
{{out}}
<pre>Atn(1/2) + Atn(1/3) = 1
2Atn(1/3) + Atn(1/7) = 1
4Atn(1/5) - Atn(1/239) = 1
5Atn(1/7) + 2Atn(3/79) = 1
Atn(1/2) + Atn(1/5) + Atn(1/8) = 1
4Atn(1/5) - Atn(1/70) + Atn(1/99) = 1
5Atn(1/7) + 4Atn(1/53) + 2Atn(1/4443) = 1
6Atn(1/8) + 2Atn(1/57) + Atn(1/239) = 1
8Atn(1/10) - Atn(1/239) - 4Atn(1/515) = 1
12Atn(1/18) + 8Atn(1/57) - 5Atn(1/239) = 1
16Atn(1/21) + 3Atn(1/239) + 4Atn(3/1042) = 1
22Atn(1/28) + 2Atn(1/443) - 5Atn(1/1393) - 10Atn(1/11018) = 1
22Atn(1/38) + 17Atn(7/601) + 10Atn(7/8149) = 1
44Atn(1/57) + 7Atn(1/239) - 12Atn(1/682) + 24Atn(1/12943) = 1
88Atn(1/172) + 51Atn(1/239) + 32Atn(1/682) + 44Atn(1/5357) + 68Atn(1/12943) = 1
88Atn(1/172) + 51Atn(1/239) + 32Atn(1/682) + 44Atn(1/5357) + 68Atn(1/12944) = 0.999999188225744</pre>
 
=={{header|GAP}}==
The formula is entered as a list of pairs [k, x], where each pair means k*atan(x), and all the terms in the list are summed. Like most other solutions, the program will only check that the tangent of the resulting sum is 1. For instance, <code>Check([[5, 1/2], [5, 1/3]]);</code> returns also <code>true</code>, though the result is 5pi/4.
 
<langsyntaxhighlight lang="gap">TanPlus := function(a, b)
return (a + b) / (1 - a * b);
end;
Line 614 ⟶ 761:
[[88, 1/172], [51, 1/239], [32, 1/682], [44, 1/5357], [68, 1/12943]]], Check);
Check([[88, 1/172], [51, 1/239], [32, 1/682], [44, 1/5357], [68, 1/12944]]);</langsyntaxhighlight>
 
=={{header|Go}}==
{{trans|Python}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 681 ⟶ 827:
r := new(big.Rat)
return r.Quo(new(big.Rat).Add(a, b), r.Sub(one, r.Mul(a, b)))
}</langsyntaxhighlight>
{{out}}
Last line edited to show only most significant digits of fraction which is near, but not exactly equal to 1.
Line 704 ⟶ 850:
100928883...
</pre>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Data.Ratio
import Data.List (foldl')
 
Line 736 ⟶ 881:
 
putStr "\nnot Machin: "; print not_machin
print (tans not_machin)</langsyntaxhighlight>
 
A crazier way to do the above, exploiting the built-in exponentiation algorithms:
<langsyntaxhighlight lang="haskell">import Data.Ratio
 
-- Private type. Do not use outside of the tans function
Line 772 ⟶ 917:
 
putStr "\nnot Machin: "; print not_machin
print (tans not_machin)</langsyntaxhighlight>
 
 
=={{header|J}}==
'''Solution''':<langsyntaxhighlight lang="j"> machin =: 1r4p1 = [: +/ ({. * _3 o. %/@:}.)"1@:x:</langsyntaxhighlight>
'''Example''' (''test cases from task description''):<langsyntaxhighlight lang="j"> R =: <@:(0&".);._2 ];._2 noun define
  1  1     2
  1  1     3
Line 844 ⟶ 987:
 
   machin&> R
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1</langsyntaxhighlight>
'''Example''' (''counterexample''):<langsyntaxhighlight lang="j">   counterExample=. 12944 (<_1;_1)} >{:R
   counterExample  NB. Same as final test case with 12943 incremented to 12944
88 1   172
Line 853 ⟶ 996:
68 1 12944
   machin counterExample
0</langsyntaxhighlight>
'''Notes''': The function <tt>machin</tt> compares the results of each formula to π/4 (expressed as <tt>1r4p1</tt> in J's numeric notation). The first example above shows the results of these comparisons for each formula (with 1 for true and 0 for false). In J, arctan is expressed as <tt>_3 o. ''values''</tt> and the function <tt>x:</tt> coerces values to exact representation; thereafter J will maintain exactness throughout its calculations, as long as it can.
=={{header|Java}}==
Read formula from file. Parse and evaluate formula.
Implement Fraction class to support task.
<syntaxhighlight lang="java">
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class CheckMachinFormula {
private static String FILE_NAME = "MachinFormula.txt";
public static void main(String[] args) {
try {
runPrivate();
} catch (Exception e) {
e.printStackTrace();
}
}
 
private static void runPrivate() throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(new File(FILE_NAME)));) {
String inLine = null;
while ( (inLine = reader.readLine()) != null ) {
String[] split = inLine.split("=");
System.out.println(tanLeft(split[0].trim()) + " = " + split[1].trim().replaceAll("\\s+", " ") + " = " + tanRight(split[1].trim()));
}
}
}
private static String tanLeft(String formula) {
if ( formula.compareTo("pi/4") == 0 ) {
return "1";
}
throw new RuntimeException("ERROR 104: Unknown left side: " + formula);
}
private static final Pattern ARCTAN_PATTERN = Pattern.compile("(-{0,1}\\d+)\\*arctan\\((\\d+)/(\\d+)\\)");
private static Fraction tanRight(String formula) {
Matcher matcher = ARCTAN_PATTERN.matcher(formula);
List<Term> terms = new ArrayList<>();
while ( matcher.find() ) {
terms.add(new Term(Integer.parseInt(matcher.group(1)), new Fraction(matcher.group(2), matcher.group(3))));
}
return evaluateArctan(terms);
}
private static Fraction evaluateArctan(List<Term> terms) {
if ( terms.size() == 1 ) {
Term term = terms.get(0);
return evaluateArctan(term.coefficient, term.fraction);
}
int size = terms.size();
List<Term> left = terms.subList(0, (size+1) / 2);
List<Term> right = terms.subList((size+1) / 2, size);
return arctanFormula(evaluateArctan(left), evaluateArctan(right));
}
private static Fraction evaluateArctan(int coefficient, Fraction fraction) {
//System.out.println("C = " + coefficient + ", F = " + fraction);
if ( coefficient == 1 ) {
return fraction;
}
else if ( coefficient < 0 ) {
return evaluateArctan(-coefficient, fraction).negate();
}
if ( coefficient % 2 == 0 ) {
Fraction f = evaluateArctan(coefficient/2, fraction);
return arctanFormula(f, f);
}
Fraction a = evaluateArctan(coefficient/2, fraction);
Fraction b = evaluateArctan(coefficient - (coefficient/2), fraction);
return arctanFormula(a, b);
}
private static Fraction arctanFormula(Fraction f1, Fraction f2) {
return f1.add(f2).divide(Fraction.ONE.subtract(f1.multiply(f2)));
}
private static class Fraction {
public static final Fraction ONE = new Fraction("1", "1");
private BigInteger numerator;
private BigInteger denominator;
public Fraction(String num, String den) {
numerator = new BigInteger(num);
denominator = new BigInteger(den);
}
 
public Fraction(BigInteger num, BigInteger den) {
numerator = num;
denominator = den;
}
 
public Fraction negate() {
return new Fraction(numerator.negate(), denominator);
}
public Fraction add(Fraction f) {
BigInteger gcd = denominator.gcd(f.denominator);
BigInteger first = numerator.multiply(f.denominator.divide(gcd));
BigInteger second = f.numerator.multiply(denominator.divide(gcd));
return new Fraction(first.add(second), denominator.multiply(f.denominator).divide(gcd));
}
public Fraction subtract(Fraction f) {
return add(f.negate());
}
public Fraction multiply(Fraction f) {
BigInteger num = numerator.multiply(f.numerator);
BigInteger den = denominator.multiply(f.denominator);
BigInteger gcd = num.gcd(den);
return new Fraction(num.divide(gcd), den.divide(gcd));
}
 
public Fraction divide(Fraction f) {
return multiply(new Fraction(f.denominator, f.numerator));
}
@Override
public String toString() {
if ( denominator.compareTo(BigInteger.ONE) == 0 ) {
return numerator.toString();
}
return numerator + " / " + denominator;
}
}
private static class Term {
private int coefficient;
private Fraction fraction;
public Term(int c, Fraction f) {
coefficient = c;
fraction = f;
}
}
}
</syntaxhighlight>
 
{{out}}
<pre>
1 = 1*arctan(1/2) + 1*arctan(1/3) = 1
1 = 2*arctan(1/3) + 1*arctan(1/7) = 1
1 = 4*arctan(1/5) + -1*arctan(1/239) = 1
1 = 5*arctan(1/7) + 2*arctan(3/79) = 1
1 = 5*arctan(29/278) + 7*arctan(3/79) = 1
1 = 1*arctan(1/2) + 1*arctan(1/5) + 1*arctan(1/8) = 1
1 = 4*arctan(1/5) + -1*arctan(1/70) + 1*arctan(1/99) = 1
1 = 5*arctan(1/7) + 4*arctan(1/53) + 2*arctan(1/4443) = 1
1 = 6*arctan(1/8) + 2*arctan(1/57) + 1*arctan(1/239) = 1
1 = 8*arctan(1/10) + -1*arctan(1/239) + -4*arctan(1/515) = 1
1 = 12*arctan(1/18) + 8*arctan(1/57) + -5*arctan(1/239) = 1
1 = 16*arctan(1/21) + 3*arctan(1/239) + 4*arctan(3/1042) = 1
1 = 22*arctan(1/28) + 2*arctan(1/443) + -5*arctan(1/1393) + -10*arctan(1/11018) = 1
1 = 22*arctan(1/38) + 17*arctan(7/601) + 10*arctan(7/8149) = 1
1 = 44*arctan(1/57) + 7*arctan(1/239) + -12*arctan(1/682) + 24*arctan(1/12943) = 1
1 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12943) = 1
1 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944) = 1009288018000944050967896710431587186456256928584351786643498522649995492271475761189348270710224618853590682465929080006511691833816436374107451368838065354726517908250456341991684635768915704374493675498637876700129004484434187627909285979251682006538817341793224963346197503893270875008524149334251672855130857035205217929335932890740051319216343365800342290782260673215928499123722781078448297609548233999010983373327601187505623621602789012550584784738082074783523787011976757247516095289966708782862528690942242793667539020699840402353522108223 / 1009288837315638583415701528780402795721935641614456853534313491853293025565940011104051964874275710024625850092154664245109626053906509780125743180758231049920425664246286578958307532545458843067352531217230461290763258378749459637420702619029075083089762088232401888676895047947363883809724322868121990870409574061477638203859217672620508200713073485398199091153535700094640095900731630771349477187594074169815106104524371099618096164871416282464532355211521113449237814080332335526420331468258917484010722587072087349909684004660371264507984339711
 
</pre>
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">
using AbstractAlgebra # implements arbitrary precision rationals
 
Line 895 ⟶ 1,210:
 
runtestmats()
</langsyntaxhighlight> {{output}} <pre>
Testing matrices:
Verified as true: tan Tuple{BigInt,Rational{BigInt}}[(1, 1//2), (1, 1//3)] = 1//1
Line 903 ⟶ 1,218:
Verified as false: tan Tuple{BigInt,Rational{BigInt}}[(88, 1//172), (51, 1//239), (32, 1//682), (44, 1//5357), (68, 1//12944)] = 1009288018000944050967896710431587186456256928584351786643498522649995492271475761189348270710224618853590682465929080006511691833816436374107451368838065354726517908250456341991684635768915704374493675498637876700129004484434187627909285979251682006538817341793224963346197503893270875008524149334251672855130857035205217929335932890740051319216343365800342290782260673215928499123722781078448297609548233999010983373327601187505623621602789012550584784738082074783523787011976757247516095289966708782862528690942242793667539020699840402353522108223//1009288837315638583415701528780402795721935641614456853534313491853293025565940011104051964874275710024625850092154664245109626053906509780125743180758231049920425664246286578958307532545458843067352531217230461290763258378749459637420702619029075083089762088232401888676895047947363883809724322868121990870409574061477638203859217672620508200713073485398199091153535700094640095900731630771349477187594074169815106104524371099618096164871416282464532355211521113449237814080332335526420331468258917484010722587072087349909684004660371264507984339711
</pre>
 
=={{header|Kotlin}}==
As the JVM and Kotlin standard libraries lack a BigRational class, I've written one which just provides sufficient functionality to complete this task:
<langsyntaxhighlight lang="scala">// version 1.1.3
 
import java.math.BigInteger
Line 1,037 ⟶ 1,351:
println(")")
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,059 ⟶ 1,373:
false << 1 == tan(88*atan(1/172) + 51*atan(1/239) + 32*atan(1/682) + 44*atan(1/5357) + 68*atan(1/12944))
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="text">Tan[ArcTan[1/2] + ArcTan[1/3]] == 1
Tan[2 ArcTan[1/3] + ArcTan[1/7]] == 1
Tan[4 ArcTan[1/5] - ArcTan[1/239]] == 1
Line 1,081 ⟶ 1,394:
44 ArcTan[1/5357] + 68 ArcTan[1/12943]] == 1
Tan[88 ArcTan[1/172] + 51 ArcTan[1/239] + 32 ArcTan[1/682] +
44 ArcTan[1/5357] + 68 ArcTan[1/12944]] == 1</langsyntaxhighlight>
 
{{Out}}
Line 1,117 ⟶ 1,430:
 
False</pre>
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">trigexpand:true$
is(tan(atan(1/2)+atan(1/3))=1);
is(tan(2*atan(1/3)+atan(1/7))=1);
Line 1,136 ⟶ 1,448:
is(tan(44*atan(1/57)+7*atan(1/239)-12*atan(1/682)+24*atan(1/12943))=1);
is(tan(88*atan(1/172)+51*atan(1/239)+32*atan(1/682)+44*atan(1/5357)+68*atan(1/12943))=1);
is(tan(88*atan(1/172)+51*atan(1/239)+32*atan(1/682)+44*atan(1/5357)+68*atan(1/12944))=1);</langsyntaxhighlight>
{{out}}
<pre>(%i2)
Line 1,172 ⟶ 1,484:
(%i18)
(%o18) false</pre>
=={{header|Nim}}==
{{libheader|bignum}}
The most important part of our program is the formula parser which proceeds to a full syntactical validation. The parser builds an expression which is a sequence of terms, a term being itself composed of a factor and a fraction (the argument to arctan).
 
<syntaxhighlight lang="nim">import bignum
 
type
 
# Description of a term.
Term = object
factor: int # Multiplier (may be negative).
fract: Rat # Argument of arc tangent.
 
Expression = seq[Term]
 
# Rational 1.
let One = newRat(1)
 
 
####################################################################################################
# Formula parser.
 
type
 
# Possible tokens for parsing.
Token = enum tkPi, tkArctan, tkNumber, tkEqual, tkAdd, tkSub,
tkMul, tkDiv, tkLPar, tkRPar, tkError, tkEnd
 
# Lexer description.
Lexer = object
line: string # The line to parse.
pos: Natural # Current position of lexer.
token: Token # Current token.
value: Natural # Associated value (for numbers).
 
# Exception raised if an error is found.
SyntaxError = object of CatchableError
 
#---------------------------------------------------------------------------------------------------
 
proc initLexer(line: string): Lexer =
## Create and initialize a lexer.
result.line = line
result.pos = 0
 
#---------------------------------------------------------------------------------------------------
 
proc parseName(lexer: var Lexer; pos: Natural) =
## Parse a name.
 
# Build the name.
var pos = pos
var name = ""
while pos < lexer.line.len and (let c = lexer.line[pos]; c) in 'a'..'z':
name.add(c)
inc pos
 
# Update lexer state.
lexer.token = if name == "arctan": tkArctan
elif name == "pi": tkPi
else: tkError
lexer.pos = pos
 
#---------------------------------------------------------------------------------------------------
 
proc parseNumber(lexer: var Lexer; pos: Natural) =
## Parse a number.
 
# Build the number.
var pos = pos
var value = 0
while pos < lexer.line.len and (let c = lexer.line[pos]; c) in '0'..'9':
value = 10 * value + ord(c) - ord('0')
inc pos
 
# Update lexer state.
lexer.token = tkNumber
lexer.value = value
lexer.pos = pos
 
#---------------------------------------------------------------------------------------------------
 
proc getNextToken(lexer: var Lexer) =
## Find next token.
 
var pos = lexer.pos
var token: Token
while pos < lexer.line.len and lexer.line[pos] == ' ': inc pos
if pos == lexer.line.len:
# Reached end of string.
lexer.pos = pos
lexer.token = tkEnd
return
 
# Find token.
case lexer.line[pos]
of '=': token = tkEqual
of '+': token = tkAdd
of '-': token = tkSub
of '*': token = tkMul
of '/': token = tkDiv
of '(': token = tkLPar
of ')': token = tkRPar
of 'a'..'z':
lexer.parseName(pos)
return
of '0'..'9':
lexer.parseNumber(pos)
return
else: token = tkError
 
# Update lexer state.
lexer.pos = pos + 1
lexer.token = token
 
#---------------------------------------------------------------------------------------------------
 
template syntaxError(message: string) =
## Raise a syntax error exception.
raise newException(SyntaxError, message)
 
#---------------------------------------------------------------------------------------------------
 
proc parseFraction(lexer: var Lexer): Rat =
## Parse a fraction: number / number.
 
lexer.getNextToken()
if lexer.token != tkNumber:
syntaxError("number expected.")
let num = lexer.value
lexer.getNextToken()
if lexer.token != tkDiv:
syntaxError("“/” expected.")
lexer.getNextToken()
if lexer.token != tkNumber:
syntaxError("number expected")
if lexer.value == 0:
raise newException(ValueError, "null denominator.")
let den = lexer.value
result = newRat(num, den)
 
#---------------------------------------------------------------------------------------------------
 
proc parseTerm(lexer: var Lexer): Term =
## Parse a term: factor * arctan(fraction) or arctan(fraction).
 
lexer.getNextToken()
 
# Parse factor.
if lexer.token == tkNumber:
result.factor = lexer.value
lexer.getNextToken
if lexer.token != tkMul:
syntaxError("“*” expected.")
lexer.getNextToken()
else:
result.factor = 1
 
# Parse arctan.
if lexer.token != tkArctan:
syntaxError("“arctan” expected.")
lexer.getNextToken()
if lexer.token != tkLPar:
syntaxError("“(” expected.")
result.fract = lexer.parseFraction()
lexer.getNextToken()
if lexer.token != tkRPar:
syntaxError("“)” expected.")
 
#---------------------------------------------------------------------------------------------------
 
proc parse(line: string): Expression =
## Parse a formula.
 
var lexer = initLexer(line)
lexer.getNextToken()
 
if lexer.token != tkPi:
syntaxError("pi symbol expected.")
lexer.getNextToken()
 
if lexer.token != tkDiv:
syntaxError("'/' expected.")
lexer.getNextToken()
 
if lexer.token != tkNumber:
syntaxError("number expected.")
if lexer.value != 4:
raise newException(ValueError, "value 4 expected.")
lexer.getNextToken()
 
if lexer.token != tkEqual:
syntaxError("“=” expected.")
result.add(lexer.parseTerm())
lexer.getNextToken()
 
# Parse the next terms.
while (let token = lexer.token; token) in {tkAdd, tkSub}:
var term = lexer.parseTerm()
if token == tkSub:
term.factor = -term.factor
result.add(term)
lexer.getNextToken()
 
if lexer.token != tkEnd:
syntaxError("invalid characters at end of formula.")
 
 
####################################################################################################
# Evaluator.
 
proc tangent(factor: int; fract: Rat): Rat =
## Compute the tangent of "factor * arctan(fract)".
 
if factor == 1:
return fract
if factor < 0:
return -tangent(-factor, fract)
 
# Split in two parts.
let n = factor div 2
let a = tangent(n, fract)
let b = tangent(factor - n, fract)
result = (a + b) / (One - a * b)
 
#---------------------------------------------------------------------------------------------------
 
proc tangent(expr: Expression): Rat =
## Compute the tangent of a sum of terms.
 
if expr.len == 1:
result = tangent(expr[0].factor, expr[0].fract)
else:
# Split in two parts.
let a = tangent(expr[0..<(expr.len div 2)])
let b = tangent(expr[(expr.len div 2)..^1])
result = (a + b) / (One - a * b)
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
when isMainModule:
 
const Formulas = [
"pi/4 = arctan(1/2) + arctan(1/3)",
"pi/4 = 2*arctan(1/3) + arctan(1/7)",
"pi/4 = 4*arctan(1/5) - arctan(1/239)",
"pi/4 = 5*arctan(1/7) + 2*arctan(3/79)",
"pi/4 = 5*arctan(29/278) + 7*arctan(3/79)",
"pi/4 = arctan(1/2) + arctan(1/5) + arctan(1/8)",
"pi/4 = 4*arctan(1/5) - arctan(1/70) + arctan(1/99)",
"pi/4 = 5*arctan(1/7) + 4*arctan(1/53) + 2*arctan(1/4443)",
"pi/4 = 6*arctan(1/8) + 2*arctan(1/57) + arctan(1/239)",
"pi/4 = 8*arctan(1/10) - arctan(1/239) - 4*arctan(1/515)",
"pi/4 = 12*arctan(1/18) + 8*arctan(1/57) - 5*arctan(1/239)",
"pi/4 = 16*arctan(1/21) + 3*arctan(1/239) + 4*arctan(3/1042)",
"pi/4 = 22*arctan(1/28) + 2*arctan(1/443) - 5*arctan(1/1393) - 10*arctan(1/11018)",
"pi/4 = 22*arctan(1/38) + 17*arctan(7/601) + 10*arctan(7/8149)",
"pi/4 = 44*arctan(1/57) + 7*arctan(1/239) - 12*arctan(1/682) + 24*arctan(1/12943)",
"pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12943)",
"pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944)"]
 
for formula in Formulas:
let expr = formula.parse()
let value = tangent(expr)
if value == 1:
echo "True: ", formula
else:
echo "False: ", formula
echo "Tangent of the right expression is about ", value.toFloat</syntaxhighlight>
 
{{out}}
<pre>True: pi/4 = arctan(1/2) + arctan(1/3)
True: pi/4 = 2*arctan(1/3) + arctan(1/7)
True: pi/4 = 4*arctan(1/5) - arctan(1/239)
True: pi/4 = 5*arctan(1/7) + 2*arctan(3/79)
True: pi/4 = 5*arctan(29/278) + 7*arctan(3/79)
True: pi/4 = arctan(1/2) + arctan(1/5) + arctan(1/8)
True: pi/4 = 4*arctan(1/5) - arctan(1/70) + arctan(1/99)
True: pi/4 = 5*arctan(1/7) + 4*arctan(1/53) + 2*arctan(1/4443)
True: pi/4 = 6*arctan(1/8) + 2*arctan(1/57) + arctan(1/239)
True: pi/4 = 8*arctan(1/10) - arctan(1/239) - 4*arctan(1/515)
True: pi/4 = 12*arctan(1/18) + 8*arctan(1/57) - 5*arctan(1/239)
True: pi/4 = 16*arctan(1/21) + 3*arctan(1/239) + 4*arctan(3/1042)
True: pi/4 = 22*arctan(1/28) + 2*arctan(1/443) - 5*arctan(1/1393) - 10*arctan(1/11018)
True: pi/4 = 22*arctan(1/38) + 17*arctan(7/601) + 10*arctan(7/8149)
True: pi/4 = 44*arctan(1/57) + 7*arctan(1/239) - 12*arctan(1/682) + 24*arctan(1/12943)
True: pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12943)
False: pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944)
Tangent of the right expression is about 0.9999991882257444</pre>
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">open Num;; (* use exact rationals for results *)
 
let tadd p q = (p +/ q) // ((Int 1) -/ (p */ q)) in
Line 1,225 ⟶ 1,824:
(4,[(88,1,172);(51,1,239);(32,1,682);(44,1,5357);(68,1,12943)]);
(4,[(88,1,172);(51,1,239);(32,1,682);(44,1,5357);(68,1,12944)])
]</langsyntaxhighlight>
 
Compile with
Line 1,269 ⟶ 1,868:
tan(RHS) is not one
</pre>
 
=={{header|ooRexx}}==
<langsyntaxhighlight lang="oorexx">/*REXX ----------------------------------------------------------------
* 09.04.2014 Walter Pachl the REXX solution adapted for ooRexx
* which provides a function package rxMath
Line 1,299 ⟶ 1,897:
end /*j*/ /* [?] show OK | bad, formula. */
::requires rxmath library
</syntaxhighlight>
</lang>
{{out}}
<pre> OK: pi/4=rxCalcarctan(1/2,16,R)+rxCalcarctan(1/3,16,R)
Line 1,318 ⟶ 1,916:
OK: pi/4=88*rxCalcarctan(1/172,16,R)+51*rxCalcarctan(1/239,16,R)+32*rxCalcarctan(1/682,16,R)+44*rxCalcarctan(1/5357,16,R)+68*rxCalcarctan(1/12943,16,R)
bad: pi/4=88*rxCalcarctan(1/172,16,R)+51*rxCalcarctan(1/239,16,R)+32*rxCalcarctan(1/682,16,R)+44*rxCalcarctan(1/5357,16,R)+68*rxCalcarctan(1/12944,16,R)</pre>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">tanEval(coef, f)={
if (coef <= 1, return(if(coef<1,-tanEval(-coef, f),f)));
my(a=tanEval(coef\2, f), b=tanEval(coef-coef\2, f));
Line 1,350 ⟶ 1,947:
test([[44,1/57],[7,1/239],[-12,1/682],[24,1/12943]]);
test([[88,1/172],[51,1/239],[32,1/682],[44,1/5357],[68,1/12943]]);
test([[88,1/172],[51,1/239],[32,1/682],[44,1/5357],[68,1/12944]]);</langsyntaxhighlight>
{{out}}
<pre>OK
Line 1,369 ⟶ 1,966:
OK
Error: [[88, 1/172], [51, 1/239], [32, 1/682], [44, 1/5357], [68, 1/12944]]</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">use Math::BigRat try=>"GMP";
 
sub taneval {
Line 1,410 ⟶ 2,006:
test([44,'1/57'],[7,'1/239'],[-12,'1/682'],[24,'1/12943']);
test([88,'1/172'],[51,'1/239'],[32,'1/682'],[44,'1/5357'],[68,'1/12943']);
test([88,'1/172'],[51,'1/239'],[32,'1/682'],[44,'1/5357'],[68,'1/12944']);</langsyntaxhighlight>
{{out}}
<pre> OK ([1 1/2] [1 1/3])
Line 1,429 ⟶ 2,025:
OK ([88 1/172] [51 1/239] [32 1/682] [44 1/5357] [68 1/12943])
Error ([88 1/172] [51 1/239] [32 1/682] [44 1/5357] [68 1/12944])</pre>
=={{header|Phix}}==
===Naive version===
Rather than test tan(a) for 1.0, test whether the sprint of it, which is rounded to 10 significant digits, is "1.0" or "1".<br>
At the end we deliberately show a test case that should and does fail.
 
<!--<syntaxhighlight lang="phix">(phixonline)-->
=={{header|Perl 6}}==
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
{{Works with|rakudo|2018.03}}
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
The coercion to FatRat provides for exact computation for all input.
<span style="color: #008080;">if</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">*</span><span style="color: #004600;">PI</span><span style="color: #0000FF;">/</span><span style="color: #000000;">4</span> <span style="color: #0000FF;">>=</span> <span style="color: #000000;">a</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">if</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">*</span><span style="color: #004600;">PI</span><span style="color: #0000FF;">/</span><span style="color: #000000;">4</span> <span style="color: #0000FF;"><=</span> <span style="color: #000000;">a</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{{trans|Perl}}
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">))</span>
<lang perl6>sub taneval ($coef, $f) {
<span style="color: #0000FF;">?</span><span style="color: #000000;">s</span> <span style="color: #000080;font-style:italic;">-- or test for "1.0"/"1", but not 1.0</span>
return 0 if $coef == 0;
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
return $f if $coef == 1;
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">))</span>
return -taneval(-$coef, $f) if $coef < 0;
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">))</span>
 
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">239</span><span style="color: #0000FF;">))</span>
my $a = taneval($coef+>1, $f);
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">79</span><span style="color: #0000FF;">))</span>
my $b = taneval($coef - $coef+>1, $f);
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">29</span><span style="color: #0000FF;">/</span> <span style="color: #000000;">278</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">79</span><span style="color: #0000FF;">))</span>
($a+$b)/(1-$a*$b);
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">))</span>
}
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">70</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">99</span><span style="color: #0000FF;">))</span>
 
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">53</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">4443</span><span style="color: #0000FF;">))</span>
sub tans (@xs) {
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">57</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">239</span><span style="color: #0000FF;">))</span>
return taneval(@xs[0;0], @xs[0;1].FatRat) if @xs == 1;
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">239</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">515</span><span style="color: #0000FF;">))</span>
 
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">12</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">18</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">57</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">239</span><span style="color: #0000FF;">))</span>
my $a = tans(@xs[0 .. (-1+@xs+>1)]);
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">16</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">21</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">239</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">1042</span><span style="color: #0000FF;">))</span>
my $b = tans(@xs[(-1+@xs+>1)+1 .. -1+@xs]);
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">22</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">28</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">443</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">1393</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">11018</span><span style="color: #0000FF;">))</span>
($a+$b)/(1-$a*$b);
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">22</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">38</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">17</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">7</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">601</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span><span style="color: #000000;">10</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">7</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">8149</span><span style="color: #0000FF;">))</span>
}
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">44</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">57</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">239</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">12</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">682</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">24</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">12943</span><span style="color: #0000FF;">))</span>
 
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">88</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">172</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">51</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">239</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span><span style="color: #000000;">32</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">682</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">44</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">5357</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">68</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">12943</span><span style="color: #0000FF;">))</span>
sub verify (@eqn) {
<span style="color: #0000FF;">?</span><span style="color: #008000;">"==="</span>
printf "%5s (%s)\n", (tans(@eqn) == 1) ?? "OK" !! "Error",
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">88</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">172</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">51</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">239</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">682</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">44</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">5357</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">68</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">arctan</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">12944</span><span style="color: #0000FF;">))</span>
(map { "[{.[0]} {.[1].nude.join('/')}]" }, @eqn).join(' ');
<!--</syntaxhighlight>-->
}
 
verify($_) for
([[1,1/2], [1,1/3]],
[[2,1/3], [1,1/7]],
[[4,1/5], [-1,1/239]],
[[5,1/7], [2,3/79]],
[[5,29/278], [7,3/79]],
[[1,1/2], [1,1/5], [1,1/8]],
[[4,1/5], [-1,1/70], [1,1/99]],
[[5,1/7], [4,1/53], [2,1/4443]],
[[6,1/8], [2,1/57], [1,1/239]],
[[8,1/10], [-1,1/239], [-4,1/515]],
[[12,1/18], [8,1/57], [-5,1/239]],
[[16,1/21], [3,1/239], [4,3/1042]],
[[22,1/28], [2,1/443], [-5,1/1393], [-10,1/11018]],
[[22,1/38], [17,7/601], [10,7/8149]],
[[44,1/57], [7,1/239], [-12,1/682], [24,1/12943]],
[[88,1/172], [51,1/239], [32,1/682], [44,1/5357], [68,1/12943]],
[[88,1/172], [51,1/239], [32,1/682], [44,1/5357], [68,1/21944]]
);</lang>
{{out}}
<pre> OK ([1 1/2] [1 1/3])
OK ([2 1/3] [1 1/7])
OK ([4 1/5] [-1 1/239])
OK ([5 1/7] [2 3/79])
OK ([5 29/278] [7 3/79])
OK ([1 1/2] [1 1/5] [1 1/8])
OK ([4 1/5] [-1 1/70] [1 1/99])
OK ([5 1/7] [4 1/53] [2 1/4443])
OK ([6 1/8] [2 1/57] [1 1/239])
OK ([8 1/10] [-1 1/239] [-4 1/515])
OK ([12 1/18] [8 1/57] [-5 1/239])
OK ([16 1/21] [3 1/239] [4 3/1042])
OK ([22 1/28] [2 1/443] [-5 1/1393] [-10 1/11018])
OK ([22 1/38] [17 7/601] [10 7/8149])
OK ([44 1/57] [7 1/239] [-12 1/682] [24 1/12943])
OK ([88 1/172] [51 1/239] [32 1/682] [44 1/5357] [68 1/12943])
Error ([88 1/172] [51 1/239] [32 1/682] [44 1/5357] [68 1/21944])</pre>
 
=={{header|Phix}}==
===Naieve version===
Hint: rather than test tan(a) for 1.0, test whether the sprint of it, which is rounded to 10 significant digits, is "1.0".<br>
The failing test case, I believe, is only accurate to 6 (or perhaps 7, see fractions output) significant digits.
<lang Phix>procedure test(atom a)
if -3*PI/4 >= a then ?9/0 end if
if 5*PI/4 <= a then ?9/0 end if
string s = sprint(tan(a))
?s -- or test for "1.0", but not 1.0
end procedure
test( arctan(1 / 2) + arctan(1 / 3))
test( 2*arctan(1 / 3) + arctan(1 / 7))
test( 4*arctan(1 / 5) - arctan(1 / 239))
test( 5*arctan(1 / 7) + 2*arctan(3 / 79))
test( 5*arctan(29/ 278) + 7*arctan(3 / 79))
test( arctan(1 / 2) + arctan(1 / 5) + arctan(1 / 8))
test( 4*arctan(1 / 5) - arctan(1 / 70) + arctan(1 / 99))
test( 5*arctan(1 / 7) + 4*arctan(1 / 53) + 2*arctan(1 / 4443))
test( 6*arctan(1 / 8) + 2*arctan(1 / 57) + arctan(1 / 239))
test( 8*arctan(1 / 10) - arctan(1 / 239) - 4*arctan(1 / 515))
test(12*arctan(1 / 18) + 8*arctan(1 / 57) - 5*arctan(1 / 239))
test(16*arctan(1 / 21) + 3*arctan(1 / 239) + 4*arctan(3 / 1042))
test(22*arctan(1 / 28) + 2*arctan(1 / 443) - 5*arctan(1 / 1393) - 10*arctan(1 / 11018))
test(22*arctan(1 / 38) + 17*arctan(7 / 601) +10*arctan(7 / 8149))
test(44*arctan(1 / 57) + 7*arctan(1 / 239) -12*arctan(1 / 682) + 24*arctan(1 / 12943))
test(88*arctan(1 / 172) + 51*arctan(1 / 239) +32*arctan(1 / 682) + 44*arctan(1 / 5357) + 68*arctan(1 / 12943))
?"==="
test(88*arctan(1 / 172) + 51*arctan(1 / 239) + 32*arctan(1 / 682) + 44*arctan(1 / 5357) + 68*arctan(1 / 12944))</lang>
{{out}}
<pre>
Line 1,547 ⟶ 2,080:
 
===Using proper fractions===
{{translibheader|DPhix/mpfr}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
Routines adapted from [[Arithmetic/Rational#Phix]]<br>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<lang Phix>include builtins\pfrac.e -- (provisional/0.8.0+)
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
 
function tans(sequence x)
<span style="color: #008080;">function</span> <span style="color: #000000;">tans</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
frac a,b
<span style="color: #004080;">sequence</span> <span style="color: #000000;">args</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">))</span>
integer h
<span style="color: #004080;">mpq</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">aab</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mab</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpq_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span>
if length(x)=1 then
<span style="color: #004080;">integer</span> <span style="color: #000000;">h</span>
{integer m, frac f} = x[1]
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
if m=1 then
<span style="color: #0000FF;">{</span><span style="color: #004080;">integer</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">mpq</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
return f
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
elsif m<0 then
<span style="color: #7060A8;">mpq_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
return frac_uminus(tans({{-m,f}}))
<span style="color: #008080;">return</span> <span style="color: #000000;">a</span>
end if
<span style="color: #008080;">elsif</span> <span style="color: #000000;">m</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
h = floor(m/2)
<span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tans</span><span style="color: #0000FF;">({{-</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">}})</span>
a = tans({{h,f}})
<span style="color: #7060A8;">mpq_neg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
b = tans({{m-h,f}})
<span style="color: #008080;">return</span> <span style="color: #000000;">f</span>
else
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
h = floor(length(x)/2)
<span style="color: #000000;">h</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
a = tans(x[1..h])
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tans</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">h</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">}})</span>
b = tans(x[h+1..$])
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tans</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">m</span><span style="color: #0000FF;">-</span><span style="color: #000000;">h</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">}})</span>
end if
<span style="color: #008080;">else</span>
return frac_div(frac_add(a,b) , frac_sub(frac_new(1),frac_mul(a,b)))
<span style="color: #000000;">h</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tans</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">h</span><span style="color: #0000FF;">])</span>
 
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tans</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">h</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$])</span>
function parse(string formula)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
-- obviously the error handling here is a bit brutal...
<span style="color: #7060A8;">mpq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mab</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
sequence res = {}, r
<span style="color: #7060A8;">mpq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aab</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
integer m,n,d
<span style="color: #7060A8;">mpq_set_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
formula = substitute(formula," ","") -- strip spaces
<span style="color: #7060A8;">mpq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mab</span><span style="color: #0000FF;">)</span>
if formula[1..5]!="pi/4=" then ?9/0 end if
<span style="color: #7060A8;">mpq_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">aab</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
formula = formula[6..$]
<span style="color: #0000FF;">{</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">aab</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mab</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpq_free</span><span style="color: #0000FF;">({</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">aab</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mab</span><span style="color: #0000FF;">})</span>
res = {}
<span style="color: #008080;">return</span> <span style="color: #000000;">a</span>
while length(formula) do
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
integer sgn = +1
switch formula[1] do
<span style="color: #008080;">function</span> <span style="color: #000000;">parse</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">formula</span><span style="color: #0000FF;">)</span>
case '-': sgn = -1; fallthrough
<span style="color: #000080;font-style:italic;">-- obviously the error handling here is a bit brutal...</span>
case '+': formula = formula[2..$]
<span style="color: #000000;">formula</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">formula</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- strip spaces</span>
end switch
<span style="color: #008080;">if</span> <span style="color: #000000;">formula</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">5</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">"pi/4="</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if formula[1]='a' then
<span style="color: #000000;">formula</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">formula</span><span style="color: #0000FF;">[</span><span style="color: #000000;">6</span><span style="color: #0000FF;">..$]</span>
m = sgn
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000000;">r</span>
else
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">formula</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
r = scanf(formula,"%d*%s")
<span style="color: #004080;">integer</span> <span style="color: #000000;">sgn</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span>
if length(r)!=1 then ?9/0 end if
<span style="color: #008080;">switch</span> <span style="color: #000000;">formula</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span>
{m,formula} = r[1]
<span style="color: #008080;">case</span> <span style="color: #008000;">'-'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">sgn</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">;</span> <span style="color: #008080;">fallthrough</span>
m *= sgn
<span style="color: #008080;">case</span> <span style="color: #008000;">'+'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">formula</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">formula</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
r = scanf(formula,"arctan(%d/%d)%s")
<span style="color: #008080;">if</span> <span style="color: #000000;">formula</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'a'</span> <span style="color: #008080;">then</span>
if length(r)!=1 then ?9/0 end if
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sgn</span>
{n,d,formula} = r[1]
<span style="color: #008080;">else</span>
res = append(res,{m,frac_new(n,d)})
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">scanf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">formula</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d*%s"</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return res
<span style="color: #0000FF;">{</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">formula</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
end function
<span style="color: #000000;">m</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">sgn</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
procedure test(string formula)
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">scanf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">formula</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"arctan(%d/%d)%s"</span><span style="color: #0000FF;">)</span>
frac f = tans(parse(formula))
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if frac_eq(f,frac_one) then
<span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">formula</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
printf(1,"OK: %s\n",{formula})
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">mpq_init_set_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)})</span>
else
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
printf(1,"ERROR: %s\n",{formula})
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
printf(1," %s\n\\ %s\n",frac_sprint(f,asPair:=true))
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end if
end procedure
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">formula</span><span style="color: #0000FF;">)</span>
 
<span style="color: #004080;">mpq</span> <span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tans</span><span style="color: #0000FF;">(</span><span style="color: #000000;">parse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">formula</span><span style="color: #0000FF;">))</span>
constant formulae = {"pi/4 = arctan(1/2) + arctan(1/3)",
<span style="color: #008080;">if</span> <span style="color: #7060A8;">mpq_cmp_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
"pi/4 = 2*arctan(1/3) + arctan(1/7)",
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"OK: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">formula</span><span style="color: #0000FF;">})</span>
"pi/4 = 4*arctan(1/5) - arctan(1/239)",
<span style="color: #008080;">else</span>
"pi/4 = 5*arctan(1/7) + 2*arctan(3/79)",
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ERROR: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">formula</span><span style="color: #0000FF;">})</span>
"pi/4 = 5*arctan(29/278) + 7*arctan(3/79)",
<span style="color: #004080;">mpz</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
"pi/4 = arctan(1/2) + arctan(1/5) + arctan(1/8)",
<span style="color: #7060A8;">mpq_get_num</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
"pi/4 = 4*arctan(1/5) - arctan(1/70) + arctan(1/99)",
<span style="color: #7060A8;">mpq_get_den</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
"pi/4 = 5*arctan(1/7) + 4*arctan(1/53) + 2*arctan(1/4443)",
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %s\n\\ %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)),</span>
"pi/4 = 6*arctan(1/8) + 2*arctan(1/57) + arctan(1/239)",
<span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">))})</span>
"pi/4 = 8*arctan(1/10) - arctan(1/239) - 4*arctan(1/515)",
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
"pi/4 = 12*arctan(1/18) + 8*arctan(1/57) - 5*arctan(1/239)",
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
"pi/4 = 16*arctan(1/21) + 3*arctan(1/239) + 4*arctan(3/1042)",
"pi/4 = 22*arctan(1/28) + 2*arctan(1/443) - 5*arctan(1/1393) - 10*arctan(1/11018)",
<span style="color: #008080;">constant</span> <span style="color: #000000;">formulae</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"pi/4 = arctan(1/2) + arctan(1/3)"</span><span style="color: #0000FF;">,</span>
"pi/4 = 22*arctan(1/38) + 17*arctan(7/601) + 10*arctan(7/8149)",
<span style="color: #008000;">"pi/4 = 442*arctan(1/573) + 7*arctan(1/2397) - 12*arctan(1"</682)span><span +style="color: 24*arctan(1/12943)#0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 884*arctan(1/1725) +- 51*arctan(1/239) + 32*arctan(1"</682)span><span +style="color: 44*arctan(1/5357) + 68*arctan(1/12943)#0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 885*arctan(1/1727) + 512*arctan(13/23979) + 32*arctan(1"</682)span><span +style="color: 44*arctan(1#0000FF;">,</5357) + 68*arctan(1/12944)"}span>
<span style="color: #008000;">"pi/4 = 5*arctan(29/278) + 7*arctan(3/79)"</span><span style="color: #0000FF;">,</span>
 
<span style="color: #008000;">"pi/4 = arctan(1/2) + arctan(1/5) + arctan(1/8)"</span><span style="color: #0000FF;">,</span>
for i=1 to length(formulae) do
<span style="color: #008000;">"pi/4 = 4*arctan(1/5) - arctan(1/70) + arctan(1/99)"</span><span style="color: #0000FF;">,</span>
test(formulae[i])
<span style="color: #008000;">"pi/4 = 5*arctan(1/7) + 4*arctan(1/53) + 2*arctan(1/4443)"</span><span style="color: #0000FF;">,</span>
end for</lang>
<span style="color: #008000;">"pi/4 = 6*arctan(1/8) + 2*arctan(1/57) + arctan(1/239)"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 8*arctan(1/10) - arctan(1/239) - 4*arctan(1/515)"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 12*arctan(1/18) + 8*arctan(1/57) - 5*arctan(1/239)"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 16*arctan(1/21) + 3*arctan(1/239) + 4*arctan(3/1042)"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 22*arctan(1/28) + 2*arctan(1/443) - 5*arctan(1/1393) - 10*arctan(1/11018)"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 22*arctan(1/38) + 17*arctan(7/601) + 10*arctan(7/8149)"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 44*arctan(1/57) + 7*arctan(1/239) - 12*arctan(1/682) + 24*arctan(1/12943)"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12943)"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944)"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">formulae</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">formulae</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
As above, the last case should and does fail.
Last line manually edited (both numerator and denominator were 550-digit numbers).
<pre>
OK: pi pi/4 4 = arctan arctan(1/2) + arctan arctan(1/3)
OK: pi pi/4 4 = 2 2*arctan(1/3) + arctan arctan(1/7)
OK: pi pi/4 4 = 4 4*arctan(1/5) - arctan arctan(1/239)
OK: pi pi/4 4 = 5 5*arctan(1/7) + 2 2*arctan(3/79)
OK: pi pi/4 4 = 5 5*arctan(29/278) + 7 7*arctan(3/79)
OK: pi pi/4 4 = arctan arctan(1/2) + arctan arctan(1/5) + arctan arctan(1/8)
OK: pi pi/4 4 = 4 4*arctan(1/5) - arctan arctan(1/70) + arctan arctan(1/99)
OK: pi pi/4 4 = 5 5*arctan(1/7) + 4 4*arctan(1/53) + 2 2*arctan(1/4443)
OK: pi pi/4 4 = 6 6*arctan(1/8) + 2 2*arctan(1/57) + arctan arctan(1/239)
OK: pi pi/4 4 = 8 8*arctan(1/10) - arctan arctan(1/239) - 4 4*arctan(1/515)
OK: pi pi/4 4 = 12 12*arctan(1/18) + 8 8*arctan(1/57) - 5 5*arctan(1/239)
OK: pi pi/4 4 = 16 16*arctan(1/21) + 3 3*arctan(1/239) + 4 4*arctan(3/1042)
OK: pi pi/4 4 = 22 22*arctan(1/28) + 2 2*arctan(1/443) - 5 5*arctan(1/1393) - 10 10*arctan(1/11018)
OK: pi pi/4 4 = 22 22*arctan(1/38) + 17 17*arctan(7/601) + 10 10*arctan(7/8149)
OK: pi pi/4 4 = 44 44*arctan(1/57) + 7 7*arctan(1/239) - 12 12*arctan(1/682) + 24 24*arctan(1/12943)
OK: pi pi/4 4 = 88 88*arctan(1/172) + 51 51*arctan(1/239) + 32 32*arctan(1/682) + 44 44*arctan(1/5357) + 68 68*arctan(1/12943)
ERROR: pi pi/4 4 = 88 88*arctan(1/172) + 51 51*arctan(1/239) + 32 32*arctan(1/682) + 44 44*arctan(1/5357) + 68 68*arctan(1/12944)
  10092880180009440509...99840402353522108223 (550 digits)
10092880180009440509678967104315871864562569285843 ... 82862528690942242793667539020699840402353522108223
\ 10092888373156385834...60371264507984339711 (550 digits)
\ 10092888373156385834157015287804027957219356416144 ... 84010722587072087349909684004660371264507984339711
</pre>
 
=={{header|Python}}==
This example parses the [http://rosettacode.org/mw/index.php?title=Check_Machin-like_formulas&oldid=146749 original] equations to form an intermediate representation then does the checks.<br>
Function tans and tanEval are translations of the HaskelHaskell functions of the same names.
<langsyntaxhighlight lang="python">import re
from fractions import Fraction
from pprint import pprint as pp
Line 1,730 ⟶ 2,276:
for machin, eqn in zip(machins, equationtext.split('\n')):
ans = tans(machin)
print('%5s: %s' % ( ('OK' if ans == 1 else 'ERROR'), eqn))</langsyntaxhighlight>
 
{{out}}
Line 1,752 ⟶ 2,298:
 
'''Note:''' the [http://kodos.sourceforge.net/ Kodos] tool was used in developing the regular expression.
 
=={{header|R}}==
<langsyntaxhighlight lang="rsplus">
#lang R
library(Rmpfr)
Line 1,761 ⟶ 2,306:
# function for checking identity of tan of expression and 1, making use of high precision division operator %:%
tanident_1 <- function(x) identical(round(tan(eval(parse(text = gsub("/", "%:%", deparse(substitute(x)))))), (prec/10)), mpfr(1, prec))
</syntaxhighlight>
</lang>
 
{{out}}
<syntaxhighlight lang="r">
<lang R>
tanident_1( 1*atan(1/2) + 1*atan(1/3) )
## [1] TRUE
Line 1,799 ⟶ 2,344:
tanident_1(88*atan(1/172) + 51*atan(1/239) + 32*atan(1/682) + 44*atan(1/5357) + 68*atan(1/12944))
## [1] FALSE
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(define (reduce e)
Line 1,859 ⟶ 2,403:
(displayln "The incorrect formula reduces to:")
(reduce wrong-formula)
</syntaxhighlight>
</lang>
Output:
<langsyntaxhighlight lang="racket">
Do all correct formulas reduce to 1?
#t
The incorrect formula reduces to:
1009288018000944050967896710431587186456256928584351786643498522649995492271475761189348270710224618853590682465929080006511691833816436374107451368838065354726517908250456341991684635768915704374493675498637876700129004484434187627909285979251682006538817341793224963346197503893270875008524149334251672855130857035205217929335932890740051319216343365800342290782260673215928499123722781078448297609548233999010983373327601187505623621602789012550584784738082074783523787011976757247516095289966708782862528690942242793667539020699840402353522108223/1009288837315638583415701528780402795721935641614456853534313491853293025565940011104051964874275710024625850092154664245109626053906509780125743180758231049920425664246286578958307532545458843067352531217230461290763258378749459637420702619029075083089762088232401888676895047947363883809724322868121990870409574061477638203859217672620508200713073485398199091153535700094640095900731630771349477187594074169815106104524371099618096164871416282464532355211521113449237814080332335526420331468258917484010722587072087349909684004660371264507984339711
</syntaxhighlight>
</lang>
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2018.03}}
The coercion to FatRat provides for exact computation for all input.
 
{{trans|Perl}}
<syntaxhighlight lang="raku" line>sub taneval ($coef, $f) {
return 0 if $coef == 0;
return $f if $coef == 1;
return -taneval(-$coef, $f) if $coef < 0;
 
my $a = taneval($coef+>1, $f);
my $b = taneval($coef - $coef+>1, $f);
($a+$b)/(1-$a*$b);
}
 
sub tans (@xs) {
return taneval(@xs[0;0], @xs[0;1].FatRat) if @xs == 1;
 
my $a = tans(@xs[0 .. (-1+@xs+>1)]);
my $b = tans(@xs[(-1+@xs+>1)+1 .. -1+@xs]);
($a+$b)/(1-$a*$b);
}
 
sub verify (@eqn) {
printf "%5s (%s)\n", (tans(@eqn) == 1) ?? "OK" !! "Error",
(map { "[{.[0]} {.[1].nude.join('/')}]" }, @eqn).join(' ');
}
 
verify($_) for
([[1,1/2], [1,1/3]],
[[2,1/3], [1,1/7]],
[[4,1/5], [-1,1/239]],
[[5,1/7], [2,3/79]],
[[5,29/278], [7,3/79]],
[[1,1/2], [1,1/5], [1,1/8]],
[[4,1/5], [-1,1/70], [1,1/99]],
[[5,1/7], [4,1/53], [2,1/4443]],
[[6,1/8], [2,1/57], [1,1/239]],
[[8,1/10], [-1,1/239], [-4,1/515]],
[[12,1/18], [8,1/57], [-5,1/239]],
[[16,1/21], [3,1/239], [4,3/1042]],
[[22,1/28], [2,1/443], [-5,1/1393], [-10,1/11018]],
[[22,1/38], [17,7/601], [10,7/8149]],
[[44,1/57], [7,1/239], [-12,1/682], [24,1/12943]],
[[88,1/172], [51,1/239], [32,1/682], [44,1/5357], [68,1/12943]],
[[88,1/172], [51,1/239], [32,1/682], [44,1/5357], [68,1/21944]]
);</syntaxhighlight>
{{out}}
<pre> OK ([1 1/2] [1 1/3])
OK ([2 1/3] [1 1/7])
OK ([4 1/5] [-1 1/239])
OK ([5 1/7] [2 3/79])
OK ([5 29/278] [7 3/79])
OK ([1 1/2] [1 1/5] [1 1/8])
OK ([4 1/5] [-1 1/70] [1 1/99])
OK ([5 1/7] [4 1/53] [2 1/4443])
OK ([6 1/8] [2 1/57] [1 1/239])
OK ([8 1/10] [-1 1/239] [-4 1/515])
OK ([12 1/18] [8 1/57] [-5 1/239])
OK ([16 1/21] [3 1/239] [4 3/1042])
OK ([22 1/28] [2 1/443] [-5 1/1393] [-10 1/11018])
OK ([22 1/38] [17 7/601] [10 7/8149])
OK ([44 1/57] [7 1/239] [-12 1/682] [24 1/12943])
OK ([88 1/172] [51 1/239] [32 1/682] [44 1/5357] [68 1/12943])
Error ([88 1/172] [51 1/239] [32 1/682] [44 1/5357] [68 1/21944])</pre>
=={{header|REXX}}==
Note: &nbsp; REXX doesn't have many high─order math functions, &nbsp; so a few of them are included here.
Line 1,874 ⟶ 2,483:
 
An extra formula was added to stress test the near exactness of a value.
<langsyntaxhighlight lang="rexx">/*REXX program evaluates some Machin─like formulas and verifies their veracity. */
@.=; pi= pi(); numeric digits( length(pi) ) - length(.); numeric fuzz 3
say center(' computing with ' digits() " decimal digits ", 110, '═')
Line 1,913 ⟶ 2,522:
numeric digits; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g *.5'e'_ % 2
do j=0 while h>9; m.j=h; h=h%2+1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/; return g</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the internal default input:}}
<pre>
Line 1,935 ⟶ 2,544:
bad: pi/4 = 88*atan(1/172) + 51*atan(1/239) + 32*atan(1/682) + 44*atan(1/5357) + 68 *atan(1/12944)
bad: pi/4 = 88*atan(1/172) + 51*atan(1/239) + 32*atan(1/682) + 44*atan(1/5357) + 67.9999999994*atan(1/12943)
</pre>
=={{header|RPL}}==
RPL does not support fat integers, therefore fat fractions neither, but the precision of floating-point numbers is actually sufficient to detect the incorrect formula and validate the other ones without using any trigonometric function. The 17 formulas to be checked are stored as strings in a global variable; each string is converted into a list of coefficients and real numbers, on which <code>tan(a+b)=(tan(a)+tan(b))/(1-tan(a)*tan(b))</code> is recursively applied, in a similar way to other languages.
{ "1*arctan(1/2) + 1*arctan(1/3)"
"2*arctan(1/3) + 1*arctan(1/7)"
"4*arctan(1/5) + -1*arctan(1/239)"
"5*arctan(1/7) + 2*arctan(3/79)"
"5*arctan(29/278) + 7*arctan(3/79)"
"1*arctan(1/2) + 1*arctan(1/5) + 1*arctan(1/8)"
"4*arctan(1/5) + -1*arctan(1/70) + 1*arctan(1/99)"
"5*arctan(1/7) + 4*arctan(1/53) + 2*arctan(1/4443)"
"6*arctan(1/8) + 2*arctan(1/57) + 1*arctan(1/239)"
"8*arctan(1/10) + -1*arctan(1/239) + -4*arctan(1/515)"
"12*arctan(1/18) + 8*arctan(1/57) + -5*arctan(1/239)"
"16*arctan(1/21) + 3*arctan(1/239) + 4*arctan(3/1042)"
"22*arctan(1/28) + 2*arctan(1/443) + -5*arctan(1/1393) + -10*arctan(1/11018)"
"22*arctan(1/38) + 17*arctan(7/601) + 10*arctan(7/8149)"
"44*arctan(1/57) + 7*arctan(1/239) + -12*arctan(1/682) + 24*arctan(1/12943)"
"88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12943)"
"88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944)"
} ''''Formulas'''' STO
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
IF DUP 1 == THEN DROP
ELSE IF DUP 0 < THEN NEG '''TanEval''' NEG
ELSE DUP2 2 / IP '''TanEval''' ROT ROT
DUP 2 / IP - '''TanEval'''
+ LAST * 1 - NEG /
END END
≫ ‘'''TanEval'''’ STO
DUP 2 GET →NUM OVER 1 GET →NUM '''TanEval''' SWAP
IF DUP SIZE 3 ≥ THEN
LIST→ 2 - →LIST ROT ROT DROP2
'''TanSum''' SWAP + LAST * 1 - NEG /
ELSE DROP END
≫ ‘'''TanSum'''’ STO
≪ DUP "+" POS → eq op
≪ IF op THEN eq op 1 + OVER SIZE SUB eq 1 op 1 - SUB
ELSE "" eq END
"'" DUP ROT SWAP + + STR→
≫ ≫ ''''PopTerm'''' STO
{} SWAP WHILE DUP "" ≠ REPEAT
'''PopTerm'''
ROT OVER 1 EXGET + SWAP DUP SIZE 1 - EXGET + SWAP
END DROP
≫ ‘'''ParsExp'''’ STO
≪ 1 CF 0
1 '''Formulas''' SIZE FOR f
'''Formulas''' f GET '''ParsExp TanSum'''
IF RND 1 == THEN 1 +
ELSE
1 SF "INCORRECT: π/4 ≠ "
'''Formulas''' f GET + SWAP
END NEXT
→STR IF 1 FS? THEN " others" + END " OK" +
≫ ‘'''TASK'''’ STO
|
'''TanEval''' ''( f c -- tan(c*arctan(f)) )''
if c = 1 then return f
else if c < 0 then return -tan(-c*arctan(f))
else put a = tan((c%2)*arctan(f)) at stack level 3
get b = tan((c-c%2)*arctan(f))
return (a+b)/(-(a*b-1))
'''TanSum''' ''( { c1 f1 .. cn fn } -- result )''
Get tan(c1*arctan(f1))
if input list > 2 items
make { c2 f2 .. cn fn }
evaluate tan of { c2..fn } and add it to
otherwise drop empty list
'''PopTerm''' ''( "T1+T2+..+Tn" -- "T2+..+Tn" 'T1' )''
If input string contains "+" then split it
else string contains only the last term
convert term into algebraic expression
'''ParsExp''' ''( "Machin formula" -- { c1 f1 .. cn fn } )''
Scan the formula
extract next term
extract c and f
Drop empty string
Initialize flag and counter
Scan list of formulas
evaluate tan(formula)
if ok, increase counter
else
build error message
with incorrect formula
Finalize report
|}
{{out}}
<pre>
2: "INCORRECT: π/4 ≠ 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944)"
1: "16 others OK"
</pre>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "bigint.s7i";
include "bigrat.s7i";
Line 2,009 ⟶ 2,731:
writeln;
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,033 ⟶ 2,755:
=={{header|Sidef}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">var equationtext = <<'EOT'
pi/4 = arctan(1/2) + arctan(1/3)
pi/4 = 2*arctan(1/3) + arctan(1/7)
Line 2,094 ⟶ 2,816:
var ans = tans(machin)
printf("%5s: %s\n", (ans == 1 ? 'OK' : 'ERROR'), eqn)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,115 ⟶ 2,837:
ERROR: pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944)
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# Compute tan(atan(p)+atan(q)) using rationals
Line 2,195 ⟶ 2,916:
puts "No! '$formula' not true"
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,216 ⟶ 2,937:
No! 'pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944)' not true
</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-big}}
{{libheader|Wren-fmt}}
We already have a BigRat class so we use that.
<syntaxhighlight lang="wren">import "./big" for BigRat
import "./fmt" for Fmt
 
/** represents a term of the form: c * atan(n / d) */
=={{header|Visual Basic .NET}}==
class Term {
'''BigRat''' class based on the Arithmetic/Rational#C here at Rosetta Code.<br/>
construct new(c, n, d) {
The parser here allows for some flexibility in the input text. Case is ignored, and a variable number of spaces are allowed. Atan(), arctan(), atn() are all recognized as valid. If one of those three are not found, a warning will appear. The coefficient need not have a multiplication sign between it and the "arctan()". The left side of the equation must be pi / 4, otherwise a warning will appear.
_c = c
<lang vbnet>Imports System.Numerics
_n = n
_d = d
}
 
c { _c }
Public Class BigRat ' Big Rational Class constructed with BigIntegers
n { _n }
Implements IComparable
Publicd nu,{ de_d As BigInteger}
Public Shared Zero = New BigRat(BigInteger.Zero, BigInteger.One),
One = New BigRat(BigInteger.One, BigInteger.One)
Sub New(bRat As BigRat)
nu = bRat.nu : de = bRat.de
End Sub
Sub New(n As BigInteger, d As BigInteger)
If d = BigInteger.Zero Then _
Throw (New Exception(String.Format("tried to set a BigRat with ({0}/{1})", n, d)))
Dim bi As BigInteger = BigInteger.GreatestCommonDivisor(n, d)
If bi > BigInteger.One Then n /= bi : d /= bi
If d < BigInteger.Zero Then n = -n : d = -d
nu = n : de = d
End Sub
Shared Operator -(x As BigRat) As BigRat
Return New BigRat(-x.nu, x.de)
End Operator
Shared Operator +(x As BigRat, y As BigRat)
Return New BigRat(x.nu * y.de + x.de * y.nu, x.de * y.de)
End Operator
Shared Operator -(x As BigRat, y As BigRat) As BigRat
Return x + (-y)
End Operator
Shared Operator *(x As BigRat, y As BigRat) As BigRat
Return New BigRat(x.nu * y.nu, x.de * y.de)
End Operator
Shared Operator /(x As BigRat, y As BigRat) As BigRat
Return New BigRat(x.nu * y.de, x.de * y.nu)
End Operator
Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
Dim dif As BigRat = New BigRat(nu, de) - obj
If dif.nu < BigInteger.Zero Then Return -1
If dif.nu > BigInteger.Zero Then Return 1
Return 0
End Function
Shared Operator =(x As BigRat, y As BigRat) As Boolean
Return x.CompareTo(y) = 0
End Operator
Shared Operator <>(x As BigRat, y As BigRat) As Boolean
Return x.CompareTo(y) <> 0
End Operator
Overrides Function ToString() As String
If de = BigInteger.One Then Return nu.ToString
Return String.Format("({0}/{1})", nu, de)
End Function
Shared Function Combine(a As BigRat, b As BigRat) As BigRat
Return (a + b) / (BigRat.One - (a * b))
End Function
End Class
 
toString {
Public Structure Term ' coefficent, BigRational construction for each term
Dim c As Integer, brvar Asa BigRat= "atan(%(n)/%(d))"
return ((_c == 1) ? " + " :
Sub New(cc As Integer, bigr As BigRat)
c = cc : br (_c == bigr-1) ? " - " :
(_c < 0) ? " - %(-c)*" : " + %(c)*") + a
End Sub
}
End Structure
}
 
var tanEval // recursive function
Module Module1
tanEval = Fn.new { |c, f|
Function Eval(c As Integer, x As BigRat) As BigRat
if (c == 1) return f
If c = 1 Then Return x Else If c < 0 Then Return Eval(-c, -x)
if (c < 0) return -tanEval.call(-c, f)
Dim hc As Integer = c \ 2
var ca = (c/2).truncate
Return BigRat.Combine(Eval(hc, x), Eval(c - hc, x))
Endvar Functioncb = c - ca
var a = tanEval.call(ca, f)
var b = tanEval.call(cb, f)
return (a + b) / (BigRat.one - (a * b))
}
 
var tanSum // recursive function
Function Sum(terms As List(Of Term)) As BigRat
tanSum = Fn.new { |terms|
If terms.Count = 1 Then Return Eval(terms(0).c, terms(0).br)
if (terms.count == 1) return tanEval.call(terms[0].c, BigRat.new(terms[0].n, terms[0].d))
Dim htc As Integer = terms.Count / 2
var half = (terms.count/2).floor
Return BigRat.Combine(Sum(terms.Take(htc).ToList), Sum(terms.Skip(htc).ToList))
var a = tanSum.call(terms.take(half).toList)
End Function
var b = tanSum.call(terms.skip(half).toList)
return (a + b) / (BigRat.one - (a * b))
}
 
var T = Term // type alias
Function ParseLine(ByVal s As String) As List(Of Term)
 
ParseLine = New List(Of Term) : Dim t As String = s.ToLower, p As Integer, x As New Term(1, BigRat.Zero)
var termsList = [
While t.Contains(" ") : t = t.Replace(" ", "") : End While
[T.new(1, 1, 2), T.new(1, 1, 3)],
p = t.IndexOf("pi/4=") : If p < 0 Then _
[T.new(2, 1, 3), T.new(1, 1, 7)],
Console.WriteLine("warning: tan(left side of equation) <> 1") : ParseLine.Add(x) : Exit Function
[T.new(4, 1, 5), t = tT.Substringnew(p-1, +1, 5239)],
[T.new(5, 1, 7), T.new(2, 3, 79)],
For Each item As String In t.Split(")")
[T.new(5, 29, 278), T.new(7, 3, 79)],
If item.Length > 5 Then
[T.new(1, 1, 2), T.new(1, 1, 5), T.new(1, 1, 8)],
If (Not item.Contains("tan") OrElse item.IndexOf("a") < 0 OrElse
[T.new(4, 1, 5), T.new(-1, 1, 70), T.new(1, 1, 99)],
item.IndexOf("a") > item.IndexOf("tan")) AndAlso Not item.Contains("atn") Then
[T.new(5, 1, 7), T.new(4, 1, 53), T.new(2, 1, 4443)],
Console.WriteLine("warning: a term is mising a valid arctangent identifier on the right side of the equation: [{0})]", item)
[T.new(6, 1, 8), T.new(2, 1, 57), T.new(1, 1, 239)],
ParseLine = New List(Of Term) : ParseLine.Add(New Term(1, BigRat.Zero)) : Exit Function
[T.new(8, 1, 10), T.new(-1, 1, 239), T.new(-4, 1, 515)],
End If
[T.new(12, 1, 18), T.new(8, 1, 57), T.new(-5, 1, 239)],
x.c = 1 : x.br = New BigRat(BigRat.One)
[T.new(16, 1, 21), T.new(3, 1, 239), T.new(4, 3, 1042)],
p = item.IndexOf("/") : If p > 0 Then
[T.new(22, 1, 28), T.new(2, 1, 443), T.new(-5, 1, 1393), T.new(-10, 1, 11018)],
x.br.de = UInt64.Parse(item.Substring(p + 1))
[T.new(22, 1, 38), T.new(17, 7, 601), T.new(10, 7, 8149)],
item = item.Substring(0, p)
[T.new(44, 1, 57), T.new(7, 1, 239), T.new(-12, 1, 682), T.new(24, 1, 12943)],
p = item.IndexOf("(") : If p > 0 Then
[T.new(88, 1, 172), T.new(51, 1, 239), T.new(32, 1, 682), T.new(44, 1, 5357), T.new(68, 1, 12943)],
x.br.nu = UInt64.Parse(item.Substring(p + 1))
[T.new(88, 1, 172), T.new(51, 1, 239), T.new(32, 1, 682), T.new(44, 1, 5357), T.new(68, 1, 12944)]
p = item.IndexOf("a") : If p > 0 Then
]
Integer.TryParse(item.Substring(0, p).Replace("*", ""), x.c)
 
If x.c = 0 Then x.c = 1
for (terms in termsList) {
If item.Contains("-") AndAlso x.c > 0 Then x.c = -x.c
var f = Fmt.swrite("$-5s: 1 == tan(", tanSum.call(terms) == BigRat.one)
End If
System.write(f)
ParseLine.Add(x)
System.write(terms[0].toString.skip(3).join())
End If
for (i in 1...terms.count) System.write(terms[i])
End If
System.print(")")
End If
}</syntaxhighlight>
Next
End Function
 
Sub Main(ByVal args As String())
Dim nl As String = vbLf
For Each item In ("pi/4 = ATan(1 / 2) + ATan(1/3)" & nl &
"pi/4 = 2Atan(1/3) + ATan(1/7)" & nl &
"pi/4 = 4ArcTan(1/5) - ATan(1 / 239)" & nl &
"pi/4 = 5arctan(1/7) + 2 * atan(3/79)" & nl &
"Pi/4 = 5ATan(29/278) + 7*ATan(3/79)" & nl &
"pi/4 = atn(1/2) + ATan(1/5) + ATan(1/8)" & nl &
"PI/4 = 4ATan(1/5) - Atan(1/70) + ATan(1/99)" & nl &
"pi /4 = 5*ATan(1/7) + 4 ATan(1/53) + 2ATan(1/4443)" & nl &
"pi / 4 = 6ATan(1/8) + 2arctangent(1/57) + ATan(1/239)" & nl &
"pi/ 4 = 8ATan(1/10) - ATan(1/239) - 4ATan(1/515)" & nl &
"pi/4 = 12ATan(1/18) + 8ATan(1/57) - 5ATan(1/239)" & nl &
"pi/4 = 16 * ATan(1/21) + 3ATan(1/239) + 4ATan(3/1042)" & nl &
"pi/4 = 22ATan(1/28) + 2ATan(1/443) - 5ATan(1/1393) - 10 ATan( 1 / 11018 )" & nl &
"pi/4 = 22ATan(1/38) + 17ATan(7/601) + 10ATan(7 / 8149)" & nl &
"pi/4 = 44ATan(1/57) + 7ATan(1/239) - 12ATan(1/682) + 24ATan(1/12943)" & nl &
"pi/4 = 88ATan(1/172) + 51ATan(1/239) + 32ATan(1/682) + 44ATan(1/5357) + 68ATan(1/12943)" & nl &
"pi/4 = 88ATan(1/172) + 51ATan(1/239) + 32ATan(1/682) + 44ATan(1/5357) + 68ATan(1/12944)").Split(nl)
Console.WriteLine("{0}: {1}", If(Sum(ParseLine(item)) = BigRat.One, "Pass", "Fail"), item)
Next
End Sub
End Module</lang>
{{out}}
<pre>
<pre>Pass: pi/4 = ATan(1 / 2) + ATan(1/3)
Passtrue : pi/41 == 2Atantan(atan(1/32) + ATanatan(1/73))
Passtrue : pi/41 == 4ArcTantan(2*atan(1/53) -+ ATanatan(1 / 2397))
Passtrue : pi/41 == 5arctantan(4*atan(1/75) + 2 *- atan(31/79239))
Passtrue : pi/41 == 5ATantan(295*atan(1/2787) + 72*ATanatan(3/79))
Passtrue : pi/41 == atntan(15*atan(29/2278) + ATan7*atan(13/579) + ATan(1/8)
Passtrue : pi/4 1 == 4ATantan(atan(1/52) -+ Atanatan(1/705) + ATanatan(1/998))
Passtrue : pi /41 == 5tan(4*ATanatan(1/75) + 4- ATanatan(1/5370) + 2ATanatan(1/444399))
Passtrue : pi / 41 == 6ATantan(5*atan(1/87) + 2arctangent4*atan(1/5753) + ATan2*atan(1/2394443))
Passtrue : pi/ 41 == 8ATantan(6*atan(1/108) -+ ATan2*atan(1/23957) -+ 4ATanatan(1/515239))
Passtrue : pi/41 == 12ATantan(8*atan(1/1810) +- 8ATanatan(1/57239) - 5ATan4*atan(1/239515))
Passtrue : pi/41 == 16 tan(12* ATanatan(1/2118) + 3ATan8*atan(1/23957) +- 4ATan5*atan(31/1042239))
Passtrue : pi/41 == 22ATantan(16*atan(1/2821) + 2ATan3*atan(1/443239) -+ 5ATan4*atan(13/13931042) - 10 ATan( 1 / 11018 )
Passtrue : pi/41 == 22ATantan(22*atan(1/3828) + 17ATan2*atan(71/601443) +- 10ATan5*atan(7 1/1393) - 814910*atan(1/11018))
Passtrue : pi/41 == 44ATantan(22*atan(1/5738) + 7ATan17*atan(17/239601) -+ 12ATan10*atan(17/6828149) + 24ATan(1/12943)
Passtrue : pi/41 == 88ATantan(44*atan(1/17257) + 51ATan7*atan(1/239) +- 32ATan12*atan(1/682) + 44ATan24*atan(1/535712943) + 68ATan(1/12943)
Failtrue : pi/41 == 88ATantan(88*atan(1/172) + 51ATan51*atan(1/239) + 32ATan32*atan(1/682) + 44ATan44*atan(1/5357) + 68ATan68*atan(1/1294412943))</pre>
false: 1 == tan(88*atan(1/172) + 51*atan(1/239) + 32*atan(1/682) + 44*atan(1/5357) + 68*atan(1/12944))
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">code ChOut=8, Text=12; \intrinsic routines
int Number(18); \numbers from equations
def LF=$0A; \ASCII line feed (end-of-line character)
Line 2,463 ⟶ 3,132:
repeat ChOut(0, SS(0)); SS:= SS+1 until SS(0)=LF; ChOut(0, LF); \show equation
];
]</langsyntaxhighlight>
 
{{out}}
9,482

edits