Continued fraction/Arithmetic/Construct from rational number: Difference between revisions

→‎{{header|Go}}: Update Go to match other (upcoming) Continued_fraction/* tasks.
(→‎{{header|Go}}: Add Go solution)
(→‎{{header|Go}}: Update Go to match other (upcoming) Continued_fraction/* tasks.)
Line 568:
 
=={{header|Go}}==
File <code>cf.go</code>:
<lang Go>package main
<lang Go>package cf
 
import (
"fmt"
"math"
"strings"
)
 
// ContinuedFraction is a regular continued fraction.
type NextFn func() (term int64, more bool)
type ContinuedFraction func() NextFn
 
// NextFn is a function/closure that can return
// a posibly infinite sequence of values.
type NextFn func() (term int64, ok bool)
 
// String implements fmt.Stringer.
// It formats a maximum of 20 values, ending the
// sequence with ", ..." if the sequence is longer.
func (cf ContinuedFraction) String() string {
var buf strings.Builder
buf.WriteByte('[')
next := cf()
t, more := next()
fmt.Fprintf(&buf, "[%d", t)
sep := "; "
const maxTerms = 20
for nnext := 0; more; n++ {cf()
if for n >:= maxTerms0; ; n++ {
t, ok := next()
fmt.Fprint(&buf, ", ...")
if !ok {
break
}
t,if moren => next()0 {
buf.WriteString(sep)
fmt.Fprintf(&buf, "%s%d", sep, t)
sep = ", "
}
if n >= maxTerms {
buf.WriteString("...")
break
}
fmt.Fprint(&buf, t)
}
buf.WriteByte(']')
fmt.Fprint(&buf, "]")
return buf.String()
}
 
// Sqrt2 is the continued fraction for √2, [1; 2, 2, 2, ...].
func Sqrt2() NextFn {
first := true
return func() (int64, bool) {
if first {
first = false
return 1, true
}
return 2, true
}
}
 
// Phi is the continued fraction for ϕ, [1; 1, 1, 1, ...].
func Phi() NextFn {
return func() (int64, bool) { return 1, true }
}
 
// E is the continued fraction for e,
// [2; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, ...].
func E() NextFn {
var i int
return func() (int64, bool) {
i++
switch {
case i == 1:
return 2, true
case i%3 == 0:
return int64(i/3) * 2, true
default:
return 1, true
}
}
}</lang>
File <code>rat.go</code>:
<lang Go>package cf
 
import "fmt"
 
// A Rat represents a quotient N/D.
type Rat struct {
N, D int64
}
 
// String implements fmt.Stringer and returns a string
// representation of `r` in the form "N/D" (even if D == 1).
func (r Rat) String() string {
return fmt.Sprintf("%d/%d", r.N, r.D)
}
 
// As ContinuedFraction returns a contined fraction representation of `r`.
func (r Rat) AsContinuedFraction() ContinuedFraction { return r.CFTerms }
func (r Rat) CFTerms() NextFn {
n, d := r.N, r.D
return func() (int64, bool) {
qif :=r.D n== /0 d{
n, d = return d0, n-q*dfalse
return q, d != 0
}
}
 
func Phi() NextFn {
return func() (int64, bool) { return 1, true }
}
 
func Sqrt2() NextFn {
first := true
return func() (int64, bool) {
if first {
first = false
return 1, true
}
q := r.N / r.D
return 2, true
r.N, r.D = r.D, r.N-q*r.D
return q, true
}
}
 
// Rosetta Code task explicitly asked for this function.,
// so here it is. We'll just use the types above instead.
func r2cf(n1, n2 int64) ContinuedFraction { return Rat{n1, n2}.CFTerms }</lang>
File <code>rat_test.go</code>:
<lang Go>package cf
 
import (
"fmt"
"math"
)
 
func mainExample_ConstructFromRational() {
cases := [...]Rat{
{1, 2},
Line 653 ⟶ 701:
approx float64
cf ContinuedFraction
d1, d2 int64
}{
{"√2", math.Sqrt2, Sqrt2, 1e4, 1e8},
{"π", math.Pi, nil, 10, 1e10},
{"ϕ", math.Phi, Phi, 10, 1e5},
{"e", math.E, E, 1e5, 1e9},
} {
fmt.Printf("\nApproximating %s ≅ %v:\n", tc.name, tc.approx)
for d := int64(10)tc.d1; d < 1e12tc.d2; d *= 10 {
n := int64(math.FloorRound(tc.approx * float64(d)))
r := Rat{n, d}
fmt.Println(r, "=", r.AsContinuedFraction())
}
if tc.cf != nil {
wid := int(math.Log10(float64(tc.d2)))*2 + 2 // ick
fmt.Println("Actual:", tc.cf)
fmt.Printf("%*s: %v\n", wid, "Actual", tc.cf)
}
}
 
// Output:
// [… commented output used by go test omitted for
// Rosetta Code listing; it is the same as below …]
}</lang>
{{out}}
Line 679 ⟶ 734:
 
Approximating √2 ≅ 1.4142135623730951:
14/10 = [1; 2, 2]
141/100 = [1; 2, 2, 3, 1, 1, 2]
1414/1000 = [1; 2, 2, 2, 2, 5, 3]
14142/10000 = [1; 2, 2, 2, 2, 2, 1, 1, 29]
141421/100000 = [1; 2, 2, 2, 2, 2, 2, 3, 1, 1, 3, 1, 7, 2]
14142131414214/1000000 = [1; 2, 2, 2, 2, 2, 2, 2, 13, 1, 4, 1, 1, 1, 16, 1, 2, 1, 612]
1414213514142136/10000000 = [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 1, 5942, 4, 1, 1, 2]
141421356/100000000 = Actual: [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 42, 12, 12, 2, 62, 2, 2, 2, 8...]
1414213562/1000000000 = [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 14, 1, 238, 1, 3]
14142135623/10000000000 = [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 3, 8, 9, 1, 20, 1, ...]
141421356237/100000000000 = [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 4, 1, 2, 1, 63, ...]
Actual: [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...]
 
Approximating π ≅ 3.141592653589793:
31/10 = [3; 10]
314/100 = [3; 7, 7]
31413142/1000 = [3; 7, 1023, 1, 5, 2]
3141531416/10000 = [3; 7, 1416, 1, 8, 211]
314159/100000 = [3; 7, 15, 1, 25, 1, 7, 4]
31415923141593/1000000 = [3; 7, 1516, 1983, 84, 64, 2]
3141592631415927/10000000 = [3; 7, 15, 1, 243354, 12, 16, 91, 14, 1, 42]
314159265/100000000 = [3; 7, 15, 1, 288, 1, 2, 1, 3, 1, 7, 4]
31415926533141592654/1000000000 = [3; 7, 15, 1, 291293, 111, 751, 1, 27, 92, 1, 3, 3, 2]
31415926535/10000000000 = [3; 7, 15, 1, 292, 1, 1, 6, 2, 13, 3, 1, 12, 3]
314159265358/100000000000 = [3; 7, 15, 1, 292, 1, 1, 1, 1, 1, 12, 1, 1, 4, 1, 1, 4, 1, 9, 1, 11]
 
Approximating ϕ ≅ 1.618033988749895:
16/10 = [1; 1, 1, 2]
161162/100 = [1; 1, 1, 1, 1, 31, 2, 2]
1618/1000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5]
16180/10000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5]
161803/100000 = Actual: [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 31, 1, 21, 1, 1, 61, 1, 2...]
 
1618033/1000000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 1, 129]
Approximating e ≅ 2.718281828459045:
16180339/10000000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 10, 15, 1, ...]
161803398271828/100000000100000 = [12; 1, 12, 1, 1, 14, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 110, 1, 1, 2, 1, 3, ...]
16180339882718282/10000000001000000 = [12; 1, 12, 1, 1, 14, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, ...141]
1618033988727182818/1000000000010000000 = [12; 1, 12, 1, 1, 14, 1, 1, 16, 1, 1, 111, 1, 12, 110, 1, 1, 1, 1, 1, 1, 16, ...2]
161803398874271828183/100000000000100000000 = [12; 1, 12, 1, 1, 14, 1, 1, 16, 1, 1, 18, 12, 1, 1, 117, 1, 1, 16, 1, 1, 1, ...]
Actual: [12; 1, 12, 1, 1, 14, 1, 1, 16, 1, 1, 18, 1, 1, 110, 1, 1, 1, 1, 112, 1, 1, ...]
</pre>
 
Anonymous user