diff options
Diffstat (limited to 'vendor/github.com/av-elier/go-decimal-to-rational')
4 files changed, 129 insertions, 0 deletions
diff --git a/vendor/github.com/av-elier/go-decimal-to-rational/.travis.yml b/vendor/github.com/av-elier/go-decimal-to-rational/.travis.yml new file mode 100644 index 00000000..e3afdd49 --- /dev/null +++ b/vendor/github.com/av-elier/go-decimal-to-rational/.travis.yml @@ -0,0 +1,10 @@ +language: go + +go: + - "1.8" + - "1.9" + - "1.10" + - "1.11" + +script: + - go test -v ./... diff --git a/vendor/github.com/av-elier/go-decimal-to-rational/LICENSE b/vendor/github.com/av-elier/go-decimal-to-rational/LICENSE new file mode 100644 index 00000000..dce70403 --- /dev/null +++ b/vendor/github.com/av-elier/go-decimal-to-rational/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Alexey Pozdnyakov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/av-elier/go-decimal-to-rational/README.md b/vendor/github.com/av-elier/go-decimal-to-rational/README.md new file mode 100644 index 00000000..6a5abe92 --- /dev/null +++ b/vendor/github.com/av-elier/go-decimal-to-rational/README.md @@ -0,0 +1,54 @@ +# go-decimal-to-rational + +[![Build Status](https://travis-ci.org/av-elier/go-decimal-to-rational.svg?branch=master)](https://travis-ci.org/av-elier/go-decimal-to-rational) + +Go library to convert decimal (float64) to rational fraction with required precision + +Relies on [Continued Fraction](http://mathworld.wolfram.com/ContinuedFraction.html) algorythm. + +It's sometimes more appropriate than default big.Rat SetString, because +you can get `2/3` from `0.6666` by specifiing required precision. In big.Rat SetString +you can only get `3333/50000`, and have no way to manipulate than (as of go 1.11). + +# Example +```go +func ExampleNewRatP() { + fmt.Println(NewRatP(0.6666, 0.01).String()) + fmt.Println(NewRatP(0.981, 0.001).String()) + fmt.Println(NewRatP(0.75, 0.01).String()) + // Output: + // 2/3 + // 981/1000 + // 3/4 +} +``` +```go +func ExampleNewRatI() { + fmt.Println(NewRatI(0.6667, 3).String()) + fmt.Println(NewRatI(0.6667, 4).String()) + // Output: + // 2/3 + // 6667/10000 +} +``` + +# Docs +``` +import dectofrac "github.com/av-elier/go-decimal-to-rational" +``` + +#### func NewRatI + +```go +func NewRatI(val float64, iterations int64) *big.Rat +``` +NewRatI returns rational from decimal using `iterations` number of +iterations in Continued Fraction algorythm + +#### func NewRatP + +```go +func NewRatP(val float64, stepPrecision float64) *big.Rat +``` +NewRatP returns rational from decimal by going as mush iterations, until +next fraction is less than `stepPrecision` diff --git a/vendor/github.com/av-elier/go-decimal-to-rational/frac.go b/vendor/github.com/av-elier/go-decimal-to-rational/frac.go new file mode 100644 index 00000000..a20f8532 --- /dev/null +++ b/vendor/github.com/av-elier/go-decimal-to-rational/frac.go @@ -0,0 +1,44 @@ +package dectofrac + +import ( + "math" + "math/big" +) + +// MaxIterations is some sane limit of iterations for precision mode +const MaxIterations = 5000 + +// NewRatI returns rational from decimal +// using `iterations` number of iterations in Continued Fraction algorythm +func NewRatI(val float64, iterations int64) *big.Rat { + return NewRat(val, iterations, 0) +} + +// NewRatP returns rational from decimal +// by going as mush iterations, until next fraction is less than `stepPrecision` +func NewRatP(val float64, stepPrecision float64) *big.Rat { + return NewRat(val, MaxIterations, stepPrecision) +} + +func NewRat(val float64, iterations int64, stepPrecision float64) *big.Rat { + a0 := int64(math.Floor(val)) + x0 := val - float64(a0) + rat := cf(x0, 1, iterations, stepPrecision) + return rat.Add(rat, new(big.Rat).SetInt64(a0)) +} + +func cf(xi float64, i int64, limit int64, stepPrecision float64) *big.Rat { + if i >= limit || xi <= stepPrecision { + return big.NewRat(0, 1) + } + + inverted := 1 / xi + aj := int64(math.Floor(inverted)) + xj := inverted - float64(aj) + ratAJ := new(big.Rat).SetInt64(aj) + ratNext := cf(xj, i+1, limit, stepPrecision) + res := ratAJ.Add(ratAJ, ratNext) + res = res.Inv(res) + + return res +} |