64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
)
|
|
|
|
type mTerm struct {
|
|
a, n, d int64
|
|
}
|
|
|
|
var testCases = [][]mTerm{
|
|
{{1, 1, 2}, {1, 1, 3}},
|
|
{{2, 1, 3}, {1, 1, 7}},
|
|
{{4, 1, 5}, {-1, 1, 239}},
|
|
{{5, 1, 7}, {2, 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, 12944}},
|
|
}
|
|
|
|
func main() {
|
|
for _, m := range testCases {
|
|
fmt.Printf("tan %v = %v\n", m, tans(m))
|
|
}
|
|
}
|
|
|
|
var one = big.NewRat(1, 1)
|
|
|
|
func tans(m []mTerm) *big.Rat {
|
|
if len(m) == 1 {
|
|
return tanEval(m[0].a, big.NewRat(m[0].n, m[0].d))
|
|
}
|
|
half := len(m) / 2
|
|
a := tans(m[:half])
|
|
b := tans(m[half:])
|
|
r := new(big.Rat)
|
|
return r.Quo(new(big.Rat).Add(a, b), r.Sub(one, r.Mul(a, b)))
|
|
}
|
|
|
|
func tanEval(coef int64, f *big.Rat) *big.Rat {
|
|
if coef == 1 {
|
|
return f
|
|
}
|
|
if coef < 0 {
|
|
r := tanEval(-coef, f)
|
|
return r.Neg(r)
|
|
}
|
|
ca := coef / 2
|
|
cb := coef - ca
|
|
a := tanEval(ca, f)
|
|
b := tanEval(cb, f)
|
|
r := new(big.Rat)
|
|
return r.Quo(new(big.Rat).Add(a, b), r.Sub(one, r.Mul(a, b)))
|
|
}
|