├── .appveyor └── appveyor.yml ├── .circleci └── config.yml ├── LICENSE ├── benchmark_test.go ├── dec.go ├── dec_go1_2_test.go ├── dec_internal_test.go ├── dec_test.go ├── example_test.go ├── rounder.go ├── rounder_example_test.go └── rounder_test.go /.appveyor/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{branch}.{build}' 2 | branches: 3 | only: 4 | - master 5 | clone_folder: c:\gopath\src\gopkg.in\inf.v0 6 | environment: 7 | GOPATH: c:\gopath 8 | install: 9 | - set Path=c:\go\bin;%Path% 10 | - echo %Path% 11 | - go version 12 | - go env 13 | build_script: 14 | - cd %APPVEYOR_BUILD_FOLDER% 15 | - go get -v -t ./... 16 | - go build -v ./... 17 | test_script: 18 | - cd %APPVEYOR_BUILD_FOLDER% 19 | - go test -v ./... 20 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | test: &test 4 | working_directory: /go/src/gopkg.in/inf.v0 5 | steps: 6 | - checkout 7 | - run: go version 8 | - run: go env 9 | - run: go get -v -t ./... 10 | - run: go test -v ./... 11 | 12 | jobs: 13 | go1.10: 14 | <<: *test 15 | docker: 16 | - image: circleci/golang:1.10 17 | go1.9: 18 | <<: *test 19 | docker: 20 | - image: circleci/golang:1.9 21 | rc: 22 | <<: *test 23 | docker: 24 | - image: circleci/golang:rc 25 | 26 | workflows: 27 | version: 2 28 | test: 29 | jobs: 30 | - go1.10 31 | - go1.9 32 | - rc 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go 2 | Authors. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /benchmark_test.go: -------------------------------------------------------------------------------- 1 | package inf 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | "math/rand" 7 | "sync" 8 | "testing" 9 | ) 10 | 11 | const maxcap = 1024 * 1024 12 | const bits = 256 13 | const maxscale = 32 14 | 15 | var once sync.Once 16 | 17 | var decInput [][2]Dec 18 | var intInput [][2]big.Int 19 | 20 | var initBench = func() { 21 | decInput = make([][2]Dec, maxcap) 22 | intInput = make([][2]big.Int, maxcap) 23 | max := new(big.Int).Lsh(big.NewInt(1), bits) 24 | r := rand.New(rand.NewSource(0)) 25 | for i := 0; i < cap(decInput); i++ { 26 | decInput[i][0].SetUnscaledBig(new(big.Int).Rand(r, max)). 27 | SetScale(Scale(r.Int31n(int32(2*maxscale-1)) - int32(maxscale))) 28 | decInput[i][1].SetUnscaledBig(new(big.Int).Rand(r, max)). 29 | SetScale(Scale(r.Int31n(int32(2*maxscale-1)) - int32(maxscale))) 30 | } 31 | for i := 0; i < cap(intInput); i++ { 32 | intInput[i][0].Rand(r, max) 33 | intInput[i][1].Rand(r, max) 34 | } 35 | } 36 | 37 | func doBenchmarkDec1(b *testing.B, f func(z *Dec)) { 38 | once.Do(initBench) 39 | b.ResetTimer() 40 | b.StartTimer() 41 | for i := 0; i < b.N; i++ { 42 | f(&decInput[i%maxcap][0]) 43 | } 44 | } 45 | 46 | func doBenchmarkDec2(b *testing.B, f func(x, y *Dec)) { 47 | once.Do(initBench) 48 | b.ResetTimer() 49 | b.StartTimer() 50 | for i := 0; i < b.N; i++ { 51 | f(&decInput[i%maxcap][0], &decInput[i%maxcap][1]) 52 | } 53 | } 54 | 55 | func doBenchmarkInt1(b *testing.B, f func(z *big.Int)) { 56 | once.Do(initBench) 57 | b.ResetTimer() 58 | b.StartTimer() 59 | for i := 0; i < b.N; i++ { 60 | f(&intInput[i%maxcap][0]) 61 | } 62 | } 63 | 64 | func doBenchmarkInt2(b *testing.B, f func(x, y *big.Int)) { 65 | once.Do(initBench) 66 | b.ResetTimer() 67 | b.StartTimer() 68 | for i := 0; i < b.N; i++ { 69 | f(&intInput[i%maxcap][0], &intInput[i%maxcap][1]) 70 | } 71 | } 72 | 73 | func Benchmark_Dec_String(b *testing.B) { 74 | doBenchmarkDec1(b, func(x *Dec) { 75 | x.String() 76 | }) 77 | } 78 | 79 | func Benchmark_Dec_StringScan(b *testing.B) { 80 | doBenchmarkDec1(b, func(x *Dec) { 81 | s := x.String() 82 | d := new(Dec) 83 | fmt.Sscan(s, d) 84 | }) 85 | } 86 | 87 | func Benchmark_Dec_GobEncode(b *testing.B) { 88 | doBenchmarkDec1(b, func(x *Dec) { 89 | x.GobEncode() 90 | }) 91 | } 92 | 93 | func Benchmark_Dec_GobEnDecode(b *testing.B) { 94 | doBenchmarkDec1(b, func(x *Dec) { 95 | g, _ := x.GobEncode() 96 | new(Dec).GobDecode(g) 97 | }) 98 | } 99 | 100 | func Benchmark_Dec_Add(b *testing.B) { 101 | doBenchmarkDec2(b, func(x, y *Dec) { 102 | ys := y.Scale() 103 | y.SetScale(x.Scale()) 104 | _ = new(Dec).Add(x, y) 105 | y.SetScale(ys) 106 | }) 107 | } 108 | 109 | func Benchmark_Dec_AddMixed(b *testing.B) { 110 | doBenchmarkDec2(b, func(x, y *Dec) { 111 | _ = new(Dec).Add(x, y) 112 | }) 113 | } 114 | 115 | func Benchmark_Dec_Sub(b *testing.B) { 116 | doBenchmarkDec2(b, func(x, y *Dec) { 117 | ys := y.Scale() 118 | y.SetScale(x.Scale()) 119 | _ = new(Dec).Sub(x, y) 120 | y.SetScale(ys) 121 | }) 122 | } 123 | 124 | func Benchmark_Dec_SubMixed(b *testing.B) { 125 | doBenchmarkDec2(b, func(x, y *Dec) { 126 | _ = new(Dec).Sub(x, y) 127 | }) 128 | } 129 | 130 | func Benchmark_Dec_Mul(b *testing.B) { 131 | doBenchmarkDec2(b, func(x, y *Dec) { 132 | _ = new(Dec).Mul(x, y) 133 | }) 134 | } 135 | 136 | func Benchmark_Dec_Mul_QuoExact(b *testing.B) { 137 | doBenchmarkDec2(b, func(x, y *Dec) { 138 | v := new(Dec).Mul(x, y) 139 | _ = new(Dec).QuoExact(v, y) 140 | }) 141 | } 142 | 143 | func Benchmark_Dec_QuoRound_Fixed_Down(b *testing.B) { 144 | doBenchmarkDec2(b, func(x, y *Dec) { 145 | _ = new(Dec).QuoRound(x, y, 0, RoundDown) 146 | }) 147 | } 148 | 149 | func Benchmark_Dec_QuoRound_Fixed_HalfUp(b *testing.B) { 150 | doBenchmarkDec2(b, func(x, y *Dec) { 151 | _ = new(Dec).QuoRound(x, y, 0, RoundHalfUp) 152 | }) 153 | } 154 | 155 | func Benchmark_Int_String(b *testing.B) { 156 | doBenchmarkInt1(b, func(x *big.Int) { 157 | x.String() 158 | }) 159 | } 160 | 161 | func Benchmark_Int_StringScan(b *testing.B) { 162 | doBenchmarkInt1(b, func(x *big.Int) { 163 | s := x.String() 164 | d := new(big.Int) 165 | fmt.Sscan(s, d) 166 | }) 167 | } 168 | 169 | func Benchmark_Int_GobEncode(b *testing.B) { 170 | doBenchmarkInt1(b, func(x *big.Int) { 171 | x.GobEncode() 172 | }) 173 | } 174 | 175 | func Benchmark_Int_GobEnDecode(b *testing.B) { 176 | doBenchmarkInt1(b, func(x *big.Int) { 177 | g, _ := x.GobEncode() 178 | new(big.Int).GobDecode(g) 179 | }) 180 | } 181 | 182 | func Benchmark_Int_Add(b *testing.B) { 183 | doBenchmarkInt2(b, func(x, y *big.Int) { 184 | _ = new(big.Int).Add(x, y) 185 | }) 186 | } 187 | 188 | func Benchmark_Int_Sub(b *testing.B) { 189 | doBenchmarkInt2(b, func(x, y *big.Int) { 190 | _ = new(big.Int).Sub(x, y) 191 | }) 192 | } 193 | 194 | func Benchmark_Int_Mul(b *testing.B) { 195 | doBenchmarkInt2(b, func(x, y *big.Int) { 196 | _ = new(big.Int).Mul(x, y) 197 | }) 198 | } 199 | 200 | func Benchmark_Int_Quo(b *testing.B) { 201 | doBenchmarkInt2(b, func(x, y *big.Int) { 202 | _ = new(big.Int).Quo(x, y) 203 | }) 204 | } 205 | 206 | func Benchmark_Int_QuoRem(b *testing.B) { 207 | doBenchmarkInt2(b, func(x, y *big.Int) { 208 | _, _ = new(big.Int).QuoRem(x, y, new(big.Int)) 209 | }) 210 | } 211 | -------------------------------------------------------------------------------- /dec.go: -------------------------------------------------------------------------------- 1 | // Package inf (type inf.Dec) implements "infinite-precision" decimal 2 | // arithmetic. 3 | // "Infinite precision" describes two characteristics: practically unlimited 4 | // precision for decimal number representation and no support for calculating 5 | // with any specific fixed precision. 6 | // (Although there is no practical limit on precision, inf.Dec can only 7 | // represent finite decimals.) 8 | // 9 | // This package is currently in experimental stage and the API may change. 10 | // 11 | // This package does NOT support: 12 | // - rounding to specific precisions (as opposed to specific decimal positions) 13 | // - the notion of context (each rounding must be explicit) 14 | // - NaN and Inf values, and distinguishing between positive and negative zero 15 | // - conversions to and from float32/64 types 16 | // 17 | // Features considered for possible addition: 18 | // + formatting options 19 | // + Exp method 20 | // + combined operations such as AddRound/MulAdd etc 21 | // + exchanging data in decimal32/64/128 formats 22 | // 23 | package inf // import "gopkg.in/inf.v0" 24 | 25 | // TODO: 26 | // - avoid excessive deep copying (quo and rounders) 27 | 28 | import ( 29 | "fmt" 30 | "io" 31 | "math/big" 32 | "strings" 33 | ) 34 | 35 | // A Dec represents a signed arbitrary-precision decimal. 36 | // It is a combination of a sign, an arbitrary-precision integer coefficient 37 | // value, and a signed fixed-precision exponent value. 38 | // The sign and the coefficient value are handled together as a signed value 39 | // and referred to as the unscaled value. 40 | // (Positive and negative zero values are not distinguished.) 41 | // Since the exponent is most commonly non-positive, it is handled in negated 42 | // form and referred to as scale. 43 | // 44 | // The mathematical value of a Dec equals: 45 | // 46 | // unscaled * 10**(-scale) 47 | // 48 | // Note that different Dec representations may have equal mathematical values. 49 | // 50 | // unscaled scale String() 51 | // ------------------------- 52 | // 0 0 "0" 53 | // 0 2 "0.00" 54 | // 0 -2 "0" 55 | // 1 0 "1" 56 | // 100 2 "1.00" 57 | // 10 0 "10" 58 | // 1 -1 "10" 59 | // 60 | // The zero value for a Dec represents the value 0 with scale 0. 61 | // 62 | // Operations are typically performed through the *Dec type. 63 | // The semantics of the assignment operation "=" for "bare" Dec values is 64 | // undefined and should not be relied on. 65 | // 66 | // Methods are typically of the form: 67 | // 68 | // func (z *Dec) Op(x, y *Dec) *Dec 69 | // 70 | // and implement operations z = x Op y with the result as receiver; if it 71 | // is one of the operands it may be overwritten (and its memory reused). 72 | // To enable chaining of operations, the result is also returned. Methods 73 | // returning a result other than *Dec take one of the operands as the receiver. 74 | // 75 | // A "bare" Quo method (quotient / division operation) is not provided, as the 76 | // result is not always a finite decimal and thus in general cannot be 77 | // represented as a Dec. 78 | // Instead, in the common case when rounding is (potentially) necessary, 79 | // QuoRound should be used with a Scale and a Rounder. 80 | // QuoExact or QuoRound with RoundExact can be used in the special cases when it 81 | // is known that the result is always a finite decimal. 82 | // 83 | type Dec struct { 84 | unscaled big.Int 85 | scale Scale 86 | } 87 | 88 | // Scale represents the type used for the scale of a Dec. 89 | type Scale int32 90 | 91 | const scaleSize = 4 // bytes in a Scale value 92 | 93 | // Scaler represents a method for obtaining the scale to use for the result of 94 | // an operation on x and y. 95 | type scaler interface { 96 | Scale(x *Dec, y *Dec) Scale 97 | } 98 | 99 | var bigInt = [...]*big.Int{ 100 | big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4), 101 | big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9), 102 | big.NewInt(10), 103 | } 104 | 105 | var exp10cache [64]big.Int = func() [64]big.Int { 106 | e10, e10i := [64]big.Int{}, bigInt[1] 107 | for i := range e10 { 108 | e10[i].Set(e10i) 109 | e10i = new(big.Int).Mul(e10i, bigInt[10]) 110 | } 111 | return e10 112 | }() 113 | 114 | // NewDec allocates and returns a new Dec set to the given int64 unscaled value 115 | // and scale. 116 | func NewDec(unscaled int64, scale Scale) *Dec { 117 | return new(Dec).SetUnscaled(unscaled).SetScale(scale) 118 | } 119 | 120 | // NewDecBig allocates and returns a new Dec set to the given *big.Int unscaled 121 | // value and scale. 122 | func NewDecBig(unscaled *big.Int, scale Scale) *Dec { 123 | return new(Dec).SetUnscaledBig(unscaled).SetScale(scale) 124 | } 125 | 126 | // Scale returns the scale of x. 127 | func (x *Dec) Scale() Scale { 128 | return x.scale 129 | } 130 | 131 | // Unscaled returns the unscaled value of x for u and true for ok when the 132 | // unscaled value can be represented as int64; otherwise it returns an undefined 133 | // int64 value for u and false for ok. Use x.UnscaledBig().Int64() to avoid 134 | // checking the validity of the value when the check is known to be redundant. 135 | func (x *Dec) Unscaled() (u int64, ok bool) { 136 | u = x.unscaled.Int64() 137 | var i big.Int 138 | ok = i.SetInt64(u).Cmp(&x.unscaled) == 0 139 | return 140 | } 141 | 142 | // UnscaledBig returns the unscaled value of x as *big.Int. 143 | func (x *Dec) UnscaledBig() *big.Int { 144 | return &x.unscaled 145 | } 146 | 147 | // SetScale sets the scale of z, with the unscaled value unchanged, and returns 148 | // z. 149 | // The mathematical value of the Dec changes as if it was multiplied by 150 | // 10**(oldscale-scale). 151 | func (z *Dec) SetScale(scale Scale) *Dec { 152 | z.scale = scale 153 | return z 154 | } 155 | 156 | // SetUnscaled sets the unscaled value of z, with the scale unchanged, and 157 | // returns z. 158 | func (z *Dec) SetUnscaled(unscaled int64) *Dec { 159 | z.unscaled.SetInt64(unscaled) 160 | return z 161 | } 162 | 163 | // SetUnscaledBig sets the unscaled value of z, with the scale unchanged, and 164 | // returns z. 165 | func (z *Dec) SetUnscaledBig(unscaled *big.Int) *Dec { 166 | z.unscaled.Set(unscaled) 167 | return z 168 | } 169 | 170 | // Set sets z to the value of x and returns z. 171 | // It does nothing if z == x. 172 | func (z *Dec) Set(x *Dec) *Dec { 173 | if z != x { 174 | z.SetUnscaledBig(x.UnscaledBig()) 175 | z.SetScale(x.Scale()) 176 | } 177 | return z 178 | } 179 | 180 | // Sign returns: 181 | // 182 | // -1 if x < 0 183 | // 0 if x == 0 184 | // +1 if x > 0 185 | // 186 | func (x *Dec) Sign() int { 187 | return x.UnscaledBig().Sign() 188 | } 189 | 190 | // Neg sets z to -x and returns z. 191 | func (z *Dec) Neg(x *Dec) *Dec { 192 | z.SetScale(x.Scale()) 193 | z.UnscaledBig().Neg(x.UnscaledBig()) 194 | return z 195 | } 196 | 197 | // Cmp compares x and y and returns: 198 | // 199 | // -1 if x < y 200 | // 0 if x == y 201 | // +1 if x > y 202 | // 203 | func (x *Dec) Cmp(y *Dec) int { 204 | xx, yy := upscale(x, y) 205 | return xx.UnscaledBig().Cmp(yy.UnscaledBig()) 206 | } 207 | 208 | // Abs sets z to |x| (the absolute value of x) and returns z. 209 | func (z *Dec) Abs(x *Dec) *Dec { 210 | z.SetScale(x.Scale()) 211 | z.UnscaledBig().Abs(x.UnscaledBig()) 212 | return z 213 | } 214 | 215 | // Add sets z to the sum x+y and returns z. 216 | // The scale of z is the greater of the scales of x and y. 217 | func (z *Dec) Add(x, y *Dec) *Dec { 218 | xx, yy := upscale(x, y) 219 | z.SetScale(xx.Scale()) 220 | z.UnscaledBig().Add(xx.UnscaledBig(), yy.UnscaledBig()) 221 | return z 222 | } 223 | 224 | // Sub sets z to the difference x-y and returns z. 225 | // The scale of z is the greater of the scales of x and y. 226 | func (z *Dec) Sub(x, y *Dec) *Dec { 227 | xx, yy := upscale(x, y) 228 | z.SetScale(xx.Scale()) 229 | z.UnscaledBig().Sub(xx.UnscaledBig(), yy.UnscaledBig()) 230 | return z 231 | } 232 | 233 | // Mul sets z to the product x*y and returns z. 234 | // The scale of z is the sum of the scales of x and y. 235 | func (z *Dec) Mul(x, y *Dec) *Dec { 236 | z.SetScale(x.Scale() + y.Scale()) 237 | z.UnscaledBig().Mul(x.UnscaledBig(), y.UnscaledBig()) 238 | return z 239 | } 240 | 241 | // Round sets z to the value of x rounded to Scale s using Rounder r, and 242 | // returns z. 243 | func (z *Dec) Round(x *Dec, s Scale, r Rounder) *Dec { 244 | return z.QuoRound(x, NewDec(1, 0), s, r) 245 | } 246 | 247 | // QuoRound sets z to the quotient x/y, rounded using the given Rounder to the 248 | // specified scale. 249 | // 250 | // If the rounder is RoundExact but the result can not be expressed exactly at 251 | // the specified scale, QuoRound returns nil, and the value of z is undefined. 252 | // 253 | // There is no corresponding Div method; the equivalent can be achieved through 254 | // the choice of Rounder used. 255 | // 256 | func (z *Dec) QuoRound(x, y *Dec, s Scale, r Rounder) *Dec { 257 | return z.quo(x, y, sclr{s}, r) 258 | } 259 | 260 | func (z *Dec) quo(x, y *Dec, s scaler, r Rounder) *Dec { 261 | scl := s.Scale(x, y) 262 | var zzz *Dec 263 | if r.UseRemainder() { 264 | zz, rA, rB := new(Dec).quoRem(x, y, scl, true, new(big.Int), new(big.Int)) 265 | zzz = r.Round(new(Dec), zz, rA, rB) 266 | } else { 267 | zz, _, _ := new(Dec).quoRem(x, y, scl, false, nil, nil) 268 | zzz = r.Round(new(Dec), zz, nil, nil) 269 | } 270 | if zzz == nil { 271 | return nil 272 | } 273 | return z.Set(zzz) 274 | } 275 | 276 | // QuoExact sets z to the quotient x/y and returns z when x/y is a finite 277 | // decimal. Otherwise it returns nil and the value of z is undefined. 278 | // 279 | // The scale of a non-nil result is "x.Scale() - y.Scale()" or greater; it is 280 | // calculated so that the remainder will be zero whenever x/y is a finite 281 | // decimal. 282 | func (z *Dec) QuoExact(x, y *Dec) *Dec { 283 | return z.quo(x, y, scaleQuoExact{}, RoundExact) 284 | } 285 | 286 | // quoRem sets z to the quotient x/y with the scale s, and if useRem is true, 287 | // it sets remNum and remDen to the numerator and denominator of the remainder. 288 | // It returns z, remNum and remDen. 289 | // 290 | // The remainder is normalized to the range -1 < r < 1 to simplify rounding; 291 | // that is, the results satisfy the following equation: 292 | // 293 | // x / y = z + (remNum/remDen) * 10**(-z.Scale()) 294 | // 295 | // See Rounder for more details about rounding. 296 | // 297 | func (z *Dec) quoRem(x, y *Dec, s Scale, useRem bool, 298 | remNum, remDen *big.Int) (*Dec, *big.Int, *big.Int) { 299 | // difference (required adjustment) compared to "canonical" result scale 300 | shift := s - (x.Scale() - y.Scale()) 301 | // pointers to adjusted unscaled dividend and divisor 302 | var ix, iy *big.Int 303 | switch { 304 | case shift > 0: 305 | // increased scale: decimal-shift dividend left 306 | ix = new(big.Int).Mul(x.UnscaledBig(), exp10(shift)) 307 | iy = y.UnscaledBig() 308 | case shift < 0: 309 | // decreased scale: decimal-shift divisor left 310 | ix = x.UnscaledBig() 311 | iy = new(big.Int).Mul(y.UnscaledBig(), exp10(-shift)) 312 | default: 313 | ix = x.UnscaledBig() 314 | iy = y.UnscaledBig() 315 | } 316 | // save a copy of iy in case it to be overwritten with the result 317 | iy2 := iy 318 | if iy == z.UnscaledBig() { 319 | iy2 = new(big.Int).Set(iy) 320 | } 321 | // set scale 322 | z.SetScale(s) 323 | // set unscaled 324 | if useRem { 325 | // Int division 326 | _, intr := z.UnscaledBig().QuoRem(ix, iy, new(big.Int)) 327 | // set remainder 328 | remNum.Set(intr) 329 | remDen.Set(iy2) 330 | } else { 331 | z.UnscaledBig().Quo(ix, iy) 332 | } 333 | return z, remNum, remDen 334 | } 335 | 336 | type sclr struct{ s Scale } 337 | 338 | func (s sclr) Scale(x, y *Dec) Scale { 339 | return s.s 340 | } 341 | 342 | type scaleQuoExact struct{} 343 | 344 | func (sqe scaleQuoExact) Scale(x, y *Dec) Scale { 345 | rem := new(big.Rat).SetFrac(x.UnscaledBig(), y.UnscaledBig()) 346 | f2, f5 := factor2(rem.Denom()), factor(rem.Denom(), bigInt[5]) 347 | var f10 Scale 348 | if f2 > f5 { 349 | f10 = Scale(f2) 350 | } else { 351 | f10 = Scale(f5) 352 | } 353 | return x.Scale() - y.Scale() + f10 354 | } 355 | 356 | func factor(n *big.Int, p *big.Int) int { 357 | // could be improved for large factors 358 | d, f := n, 0 359 | for { 360 | dd, dm := new(big.Int).DivMod(d, p, new(big.Int)) 361 | if dm.Sign() == 0 { 362 | f++ 363 | d = dd 364 | } else { 365 | break 366 | } 367 | } 368 | return f 369 | } 370 | 371 | func factor2(n *big.Int) int { 372 | // could be improved for large factors 373 | f := 0 374 | for ; n.Bit(f) == 0; f++ { 375 | } 376 | return f 377 | } 378 | 379 | func upscale(a, b *Dec) (*Dec, *Dec) { 380 | if a.Scale() == b.Scale() { 381 | return a, b 382 | } 383 | if a.Scale() > b.Scale() { 384 | bb := b.rescale(a.Scale()) 385 | return a, bb 386 | } 387 | aa := a.rescale(b.Scale()) 388 | return aa, b 389 | } 390 | 391 | func exp10(x Scale) *big.Int { 392 | if int(x) < len(exp10cache) { 393 | return &exp10cache[int(x)] 394 | } 395 | return new(big.Int).Exp(bigInt[10], big.NewInt(int64(x)), nil) 396 | } 397 | 398 | func (x *Dec) rescale(newScale Scale) *Dec { 399 | shift := newScale - x.Scale() 400 | switch { 401 | case shift < 0: 402 | e := exp10(-shift) 403 | return NewDecBig(new(big.Int).Quo(x.UnscaledBig(), e), newScale) 404 | case shift > 0: 405 | e := exp10(shift) 406 | return NewDecBig(new(big.Int).Mul(x.UnscaledBig(), e), newScale) 407 | } 408 | return x 409 | } 410 | 411 | var zeros = []byte("00000000000000000000000000000000" + 412 | "00000000000000000000000000000000") 413 | var lzeros = Scale(len(zeros)) 414 | 415 | func appendZeros(s []byte, n Scale) []byte { 416 | for i := Scale(0); i < n; i += lzeros { 417 | if n > i+lzeros { 418 | s = append(s, zeros...) 419 | } else { 420 | s = append(s, zeros[0:n-i]...) 421 | } 422 | } 423 | return s 424 | } 425 | 426 | func (x *Dec) String() string { 427 | if x == nil { 428 | return "" 429 | } 430 | scale := x.Scale() 431 | s := []byte(x.UnscaledBig().String()) 432 | if scale <= 0 { 433 | if scale != 0 && x.unscaled.Sign() != 0 { 434 | s = appendZeros(s, -scale) 435 | } 436 | return string(s) 437 | } 438 | negbit := Scale(-((x.Sign() - 1) / 2)) 439 | // scale > 0 440 | lens := Scale(len(s)) 441 | if lens-negbit <= scale { 442 | ss := make([]byte, 0, scale+2) 443 | if negbit == 1 { 444 | ss = append(ss, '-') 445 | } 446 | ss = append(ss, '0', '.') 447 | ss = appendZeros(ss, scale-lens+negbit) 448 | ss = append(ss, s[negbit:]...) 449 | return string(ss) 450 | } 451 | // lens > scale 452 | ss := make([]byte, 0, lens+1) 453 | ss = append(ss, s[:lens-scale]...) 454 | ss = append(ss, '.') 455 | ss = append(ss, s[lens-scale:]...) 456 | return string(ss) 457 | } 458 | 459 | // Format is a support routine for fmt.Formatter. It accepts the decimal 460 | // formats 'd' and 'f', and handles both equivalently. 461 | // Width, precision, flags and bases 2, 8, 16 are not supported. 462 | func (x *Dec) Format(s fmt.State, ch rune) { 463 | if ch != 'd' && ch != 'f' && ch != 'v' && ch != 's' { 464 | fmt.Fprintf(s, "%%!%c(dec.Dec=%s)", ch, x.String()) 465 | return 466 | } 467 | fmt.Fprintf(s, x.String()) 468 | } 469 | 470 | func (z *Dec) scan(r io.RuneScanner) (*Dec, error) { 471 | unscaled := make([]byte, 0, 256) // collects chars of unscaled as bytes 472 | dp, dg := -1, -1 // indexes of decimal point, first digit 473 | loop: 474 | for { 475 | ch, _, err := r.ReadRune() 476 | if err == io.EOF { 477 | break loop 478 | } 479 | if err != nil { 480 | return nil, err 481 | } 482 | switch { 483 | case ch == '+' || ch == '-': 484 | if len(unscaled) > 0 || dp >= 0 { // must be first character 485 | r.UnreadRune() 486 | break loop 487 | } 488 | case ch == '.': 489 | if dp >= 0 { 490 | r.UnreadRune() 491 | break loop 492 | } 493 | dp = len(unscaled) 494 | continue // don't add to unscaled 495 | case ch >= '0' && ch <= '9': 496 | if dg == -1 { 497 | dg = len(unscaled) 498 | } 499 | default: 500 | r.UnreadRune() 501 | break loop 502 | } 503 | unscaled = append(unscaled, byte(ch)) 504 | } 505 | if dg == -1 { 506 | return nil, fmt.Errorf("no digits read") 507 | } 508 | if dp >= 0 { 509 | z.SetScale(Scale(len(unscaled) - dp)) 510 | } else { 511 | z.SetScale(0) 512 | } 513 | _, ok := z.UnscaledBig().SetString(string(unscaled), 10) 514 | if !ok { 515 | return nil, fmt.Errorf("invalid decimal: %s", string(unscaled)) 516 | } 517 | return z, nil 518 | } 519 | 520 | // SetString sets z to the value of s, interpreted as a decimal (base 10), 521 | // and returns z and a boolean indicating success. The scale of z is the 522 | // number of digits after the decimal point (including any trailing 0s), 523 | // or 0 if there is no decimal point. If SetString fails, the value of z 524 | // is undefined but the returned value is nil. 525 | func (z *Dec) SetString(s string) (*Dec, bool) { 526 | r := strings.NewReader(s) 527 | _, err := z.scan(r) 528 | if err != nil { 529 | return nil, false 530 | } 531 | _, _, err = r.ReadRune() 532 | if err != io.EOF { 533 | return nil, false 534 | } 535 | // err == io.EOF => scan consumed all of s 536 | return z, true 537 | } 538 | 539 | // Scan is a support routine for fmt.Scanner; it sets z to the value of 540 | // the scanned number. It accepts the decimal formats 'd' and 'f', and 541 | // handles both equivalently. Bases 2, 8, 16 are not supported. 542 | // The scale of z is the number of digits after the decimal point 543 | // (including any trailing 0s), or 0 if there is no decimal point. 544 | func (z *Dec) Scan(s fmt.ScanState, ch rune) error { 545 | if ch != 'd' && ch != 'f' && ch != 's' && ch != 'v' { 546 | return fmt.Errorf("Dec.Scan: invalid verb '%c'", ch) 547 | } 548 | s.SkipSpace() 549 | _, err := z.scan(s) 550 | return err 551 | } 552 | 553 | // Gob encoding version 554 | const decGobVersion byte = 1 555 | 556 | func scaleBytes(s Scale) []byte { 557 | buf := make([]byte, scaleSize) 558 | i := scaleSize 559 | for j := 0; j < scaleSize; j++ { 560 | i-- 561 | buf[i] = byte(s) 562 | s >>= 8 563 | } 564 | return buf 565 | } 566 | 567 | func scale(b []byte) (s Scale) { 568 | for j := 0; j < scaleSize; j++ { 569 | s <<= 8 570 | s |= Scale(b[j]) 571 | } 572 | return 573 | } 574 | 575 | // GobEncode implements the gob.GobEncoder interface. 576 | func (x *Dec) GobEncode() ([]byte, error) { 577 | buf, err := x.UnscaledBig().GobEncode() 578 | if err != nil { 579 | return nil, err 580 | } 581 | buf = append(append(buf, scaleBytes(x.Scale())...), decGobVersion) 582 | return buf, nil 583 | } 584 | 585 | // GobDecode implements the gob.GobDecoder interface. 586 | func (z *Dec) GobDecode(buf []byte) error { 587 | if len(buf) == 0 { 588 | return fmt.Errorf("Dec.GobDecode: no data") 589 | } 590 | b := buf[len(buf)-1] 591 | if b != decGobVersion { 592 | return fmt.Errorf("Dec.GobDecode: encoding version %d not supported", b) 593 | } 594 | l := len(buf) - scaleSize - 1 595 | err := z.UnscaledBig().GobDecode(buf[:l]) 596 | if err != nil { 597 | return err 598 | } 599 | z.SetScale(scale(buf[l : l+scaleSize])) 600 | return nil 601 | } 602 | 603 | // MarshalText implements the encoding.TextMarshaler interface. 604 | func (x *Dec) MarshalText() ([]byte, error) { 605 | return []byte(x.String()), nil 606 | } 607 | 608 | // UnmarshalText implements the encoding.TextUnmarshaler interface. 609 | func (z *Dec) UnmarshalText(data []byte) error { 610 | _, ok := z.SetString(string(data)) 611 | if !ok { 612 | return fmt.Errorf("invalid inf.Dec") 613 | } 614 | return nil 615 | } 616 | -------------------------------------------------------------------------------- /dec_go1_2_test.go: -------------------------------------------------------------------------------- 1 | // +build go1.2 2 | 3 | package inf 4 | 5 | import ( 6 | "encoding" 7 | "encoding/json" 8 | "testing" 9 | ) 10 | 11 | var _ encoding.TextMarshaler = new(Dec) 12 | var _ encoding.TextUnmarshaler = new(Dec) 13 | 14 | type Obj struct { 15 | Val *Dec 16 | } 17 | 18 | func TestDecJsonMarshalUnmarshal(t *testing.T) { 19 | o := Obj{Val: NewDec(123, 2)} 20 | js, err := json.Marshal(o) 21 | if err != nil { 22 | t.Fatalf("json.Marshal(%v): got %v, want ok", o, err) 23 | } 24 | o2 := &Obj{} 25 | err = json.Unmarshal(js, o2) 26 | if err != nil { 27 | t.Fatalf("json.Unmarshal(%#q): got %v, want ok", js, err) 28 | } 29 | if o.Val.Scale() != o2.Val.Scale() || 30 | o.Val.UnscaledBig().Cmp(o2.Val.UnscaledBig()) != 0 { 31 | t.Fatalf("json.Unmarshal(json.Marshal(%v)): want %v, got %v", o, o, o2) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dec_internal_test.go: -------------------------------------------------------------------------------- 1 | package inf 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | ) 7 | 8 | var decQuoRemZZZ = []struct { 9 | z, x, y *Dec 10 | r *big.Rat 11 | srA, srB int 12 | }{ 13 | // basic examples 14 | {NewDec(1, 0), NewDec(2, 0), NewDec(2, 0), big.NewRat(0, 1), 0, 1}, 15 | {NewDec(15, 1), NewDec(3, 0), NewDec(2, 0), big.NewRat(0, 1), 0, 1}, 16 | {NewDec(1, 1), NewDec(1, 0), NewDec(10, 0), big.NewRat(0, 1), 0, 1}, 17 | {NewDec(0, 0), NewDec(2, 0), NewDec(3, 0), big.NewRat(2, 3), 1, 1}, 18 | {NewDec(0, 0), NewDec(2, 0), NewDec(6, 0), big.NewRat(1, 3), 1, 1}, 19 | {NewDec(1, 1), NewDec(2, 0), NewDec(12, 0), big.NewRat(2, 3), 1, 1}, 20 | 21 | // examples from the Go Language Specification 22 | {NewDec(1, 0), NewDec(5, 0), NewDec(3, 0), big.NewRat(2, 3), 1, 1}, 23 | {NewDec(-1, 0), NewDec(-5, 0), NewDec(3, 0), big.NewRat(-2, 3), -1, 1}, 24 | {NewDec(-1, 0), NewDec(5, 0), NewDec(-3, 0), big.NewRat(-2, 3), 1, -1}, 25 | {NewDec(1, 0), NewDec(-5, 0), NewDec(-3, 0), big.NewRat(2, 3), -1, -1}, 26 | } 27 | 28 | func TestDecQuoRem(t *testing.T) { 29 | for i, a := range decQuoRemZZZ { 30 | z, rA, rB := new(Dec), new(big.Int), new(big.Int) 31 | s := scaleQuoExact{}.Scale(a.x, a.y) 32 | z.quoRem(a.x, a.y, s, true, rA, rB) 33 | if a.z.Cmp(z) != 0 || a.r.Cmp(new(big.Rat).SetFrac(rA, rB)) != 0 { 34 | t.Errorf("#%d QuoRemZZZ got %v, %v, %v; expected %v, %v", i, z, rA, rB, a.z, a.r) 35 | } 36 | if a.srA != rA.Sign() || a.srB != rB.Sign() { 37 | t.Errorf("#%d QuoRemZZZ wrong signs, got %v, %v; expected %v, %v", i, rA.Sign(), rB.Sign(), a.srA, a.srB) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /dec_test.go: -------------------------------------------------------------------------------- 1 | package inf_test 2 | 3 | import ( 4 | "bytes" 5 | "encoding/gob" 6 | "fmt" 7 | "math/big" 8 | "strings" 9 | "testing" 10 | 11 | "gopkg.in/inf.v0" 12 | ) 13 | 14 | type decFunZZ func(z, x, y *inf.Dec) *inf.Dec 15 | type decArgZZ struct { 16 | z, x, y *inf.Dec 17 | } 18 | 19 | var decSumZZ = []decArgZZ{ 20 | {inf.NewDec(0, 0), inf.NewDec(0, 0), inf.NewDec(0, 0)}, 21 | {inf.NewDec(1, 0), inf.NewDec(1, 0), inf.NewDec(0, 0)}, 22 | {inf.NewDec(1111111110, 0), inf.NewDec(123456789, 0), inf.NewDec(987654321, 0)}, 23 | {inf.NewDec(-1, 0), inf.NewDec(-1, 0), inf.NewDec(0, 0)}, 24 | {inf.NewDec(864197532, 0), inf.NewDec(-123456789, 0), inf.NewDec(987654321, 0)}, 25 | {inf.NewDec(-1111111110, 0), inf.NewDec(-123456789, 0), inf.NewDec(-987654321, 0)}, 26 | {inf.NewDec(12, 2), inf.NewDec(1, 1), inf.NewDec(2, 2)}, 27 | } 28 | 29 | var decProdZZ = []decArgZZ{ 30 | {inf.NewDec(0, 0), inf.NewDec(0, 0), inf.NewDec(0, 0)}, 31 | {inf.NewDec(0, 0), inf.NewDec(1, 0), inf.NewDec(0, 0)}, 32 | {inf.NewDec(1, 0), inf.NewDec(1, 0), inf.NewDec(1, 0)}, 33 | {inf.NewDec(-991*991, 0), inf.NewDec(991, 0), inf.NewDec(-991, 0)}, 34 | {inf.NewDec(2, 3), inf.NewDec(1, 1), inf.NewDec(2, 2)}, 35 | {inf.NewDec(2, -3), inf.NewDec(1, -1), inf.NewDec(2, -2)}, 36 | {inf.NewDec(2, 3), inf.NewDec(1, 1), inf.NewDec(2, 2)}, 37 | } 38 | 39 | func TestDecSignZ(t *testing.T) { 40 | var zero inf.Dec 41 | for _, a := range decSumZZ { 42 | s := a.z.Sign() 43 | e := a.z.Cmp(&zero) 44 | if s != e { 45 | t.Errorf("got %d; want %d for z = %v", s, e, a.z) 46 | } 47 | } 48 | } 49 | 50 | func TestDecAbsZ(t *testing.T) { 51 | var zero inf.Dec 52 | for _, a := range decSumZZ { 53 | var z inf.Dec 54 | z.Abs(a.z) 55 | var e inf.Dec 56 | e.Set(a.z) 57 | if e.Cmp(&zero) < 0 { 58 | e.Sub(&zero, &e) 59 | } 60 | if z.Cmp(&e) != 0 { 61 | t.Errorf("got z = %v; want %v", z, e) 62 | } 63 | } 64 | } 65 | 66 | func testDecFunZZ(t *testing.T, msg string, f decFunZZ, a decArgZZ) { 67 | var z inf.Dec 68 | f(&z, a.x, a.y) 69 | if (&z).Cmp(a.z) != 0 { 70 | t.Errorf("%s%+v\n\tgot z = %v; want %v", msg, a, &z, a.z) 71 | } 72 | } 73 | 74 | func TestDecSumZZ(t *testing.T) { 75 | AddZZ := func(z, x, y *inf.Dec) *inf.Dec { return z.Add(x, y) } 76 | SubZZ := func(z, x, y *inf.Dec) *inf.Dec { return z.Sub(x, y) } 77 | for _, a := range decSumZZ { 78 | arg := a 79 | testDecFunZZ(t, "AddZZ", AddZZ, arg) 80 | 81 | arg = decArgZZ{a.z, a.y, a.x} 82 | testDecFunZZ(t, "AddZZ symmetric", AddZZ, arg) 83 | 84 | arg = decArgZZ{a.x, a.z, a.y} 85 | testDecFunZZ(t, "SubZZ", SubZZ, arg) 86 | 87 | arg = decArgZZ{a.y, a.z, a.x} 88 | testDecFunZZ(t, "SubZZ symmetric", SubZZ, arg) 89 | } 90 | } 91 | 92 | func TestDecProdZZ(t *testing.T) { 93 | MulZZ := func(z, x, y *inf.Dec) *inf.Dec { return z.Mul(x, y) } 94 | for _, a := range decProdZZ { 95 | arg := a 96 | testDecFunZZ(t, "MulZZ", MulZZ, arg) 97 | 98 | arg = decArgZZ{a.z, a.y, a.x} 99 | testDecFunZZ(t, "MulZZ symmetric", MulZZ, arg) 100 | } 101 | } 102 | 103 | var decUnscaledTests = []struct { 104 | d *inf.Dec 105 | u int64 // ignored when ok == false 106 | ok bool 107 | }{ 108 | {new(inf.Dec), 0, true}, 109 | {inf.NewDec(-1<<63, 0), -1 << 63, true}, 110 | {inf.NewDec(-(-1<<63 + 1), 0), -(-1<<63 + 1), true}, 111 | {new(inf.Dec).Neg(inf.NewDec(-1<<63, 0)), 0, false}, 112 | {new(inf.Dec).Sub(inf.NewDec(-1<<63, 0), inf.NewDec(1, 0)), 0, false}, 113 | {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), 0, false}, 114 | } 115 | 116 | func TestDecUnscaled(t *testing.T) { 117 | for i, tt := range decUnscaledTests { 118 | u, ok := tt.d.Unscaled() 119 | if ok != tt.ok { 120 | t.Errorf("#%d Unscaled: got %v, expected %v", i, ok, tt.ok) 121 | } else if ok && u != tt.u { 122 | t.Errorf("#%d Unscaled: got %v, expected %v", i, u, tt.u) 123 | } 124 | } 125 | } 126 | 127 | var decRoundTests = [...]struct { 128 | in *inf.Dec 129 | s inf.Scale 130 | r inf.Rounder 131 | exp *inf.Dec 132 | }{ 133 | {inf.NewDec(123424999999999993, 15), 2, inf.RoundHalfUp, inf.NewDec(12342, 2)}, 134 | {inf.NewDec(123425000000000001, 15), 2, inf.RoundHalfUp, inf.NewDec(12343, 2)}, 135 | {inf.NewDec(123424999999999993, 15), 15, inf.RoundHalfUp, inf.NewDec(123424999999999993, 15)}, 136 | {inf.NewDec(123424999999999993, 15), 16, inf.RoundHalfUp, inf.NewDec(1234249999999999930, 16)}, 137 | {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -1, inf.RoundHalfUp, inf.NewDec(1844674407370955162, -1)}, 138 | {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -2, inf.RoundHalfUp, inf.NewDec(184467440737095516, -2)}, 139 | {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -3, inf.RoundHalfUp, inf.NewDec(18446744073709552, -3)}, 140 | {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -4, inf.RoundHalfUp, inf.NewDec(1844674407370955, -4)}, 141 | {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -5, inf.RoundHalfUp, inf.NewDec(184467440737096, -5)}, 142 | {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -6, inf.RoundHalfUp, inf.NewDec(18446744073710, -6)}, 143 | } 144 | 145 | func TestDecRound(t *testing.T) { 146 | for i, tt := range decRoundTests { 147 | z := new(inf.Dec).Round(tt.in, tt.s, tt.r) 148 | if tt.exp.Cmp(z) != 0 { 149 | t.Errorf("#%d Round got %v; expected %v", i, z, tt.exp) 150 | } 151 | } 152 | } 153 | 154 | var decStringTests = []struct { 155 | in string 156 | out string 157 | val int64 158 | scale inf.Scale // skip SetString if negative 159 | ok bool 160 | scanOk bool 161 | }{ 162 | {in: "", ok: false, scanOk: false}, 163 | {in: "a", ok: false, scanOk: false}, 164 | {in: "z", ok: false, scanOk: false}, 165 | {in: "+", ok: false, scanOk: false}, 166 | {in: "-", ok: false, scanOk: false}, 167 | {in: "g", ok: false, scanOk: false}, 168 | {in: ".", ok: false, scanOk: false}, 169 | {in: ".-0", ok: false, scanOk: false}, 170 | {in: ".+0", ok: false, scanOk: false}, 171 | // Scannable but not SetStringable 172 | {"0b", "ignored", 0, 0, false, true}, 173 | {"0x", "ignored", 0, 0, false, true}, 174 | {"0xg", "ignored", 0, 0, false, true}, 175 | {"0.0g", "ignored", 0, 1, false, true}, 176 | // examples from godoc for Dec 177 | {"0", "0", 0, 0, true, true}, 178 | {"0.00", "0.00", 0, 2, true, true}, 179 | {"ignored", "0", 0, -2, true, false}, 180 | {"1", "1", 1, 0, true, true}, 181 | {"1.00", "1.00", 100, 2, true, true}, 182 | {"10", "10", 10, 0, true, true}, 183 | {"ignored", "10", 1, -1, true, false}, 184 | // other tests 185 | {"+0", "0", 0, 0, true, true}, 186 | {"-0", "0", 0, 0, true, true}, 187 | {"0.0", "0.0", 0, 1, true, true}, 188 | {"0.1", "0.1", 1, 1, true, true}, 189 | {"0.", "0", 0, 0, true, true}, 190 | {"-10", "-10", -1, -1, true, true}, 191 | {"-1", "-1", -1, 0, true, true}, 192 | {"-0.1", "-0.1", -1, 1, true, true}, 193 | {"-0.01", "-0.01", -1, 2, true, true}, 194 | {"+0.", "0", 0, 0, true, true}, 195 | {"-0.", "0", 0, 0, true, true}, 196 | {".0", "0.0", 0, 1, true, true}, 197 | {"+.0", "0.0", 0, 1, true, true}, 198 | {"-.0", "0.0", 0, 1, true, true}, 199 | {"0.0000000000", "0.0000000000", 0, 10, true, true}, 200 | {"0.0000000001", "0.0000000001", 1, 10, true, true}, 201 | {"-0.0000000000", "0.0000000000", 0, 10, true, true}, 202 | {"-0.0000000001", "-0.0000000001", -1, 10, true, true}, 203 | {"-10", "-10", -10, 0, true, true}, 204 | {"+10", "10", 10, 0, true, true}, 205 | {"00", "0", 0, 0, true, true}, 206 | {"023", "23", 23, 0, true, true}, // decimal, not octal 207 | {"-02.3", "-2.3", -23, 1, true, true}, // decimal, not octal 208 | } 209 | 210 | func TestDecGetString(t *testing.T) { 211 | z := new(inf.Dec) 212 | for i, test := range decStringTests { 213 | if !test.ok { 214 | continue 215 | } 216 | z.SetUnscaled(test.val) 217 | z.SetScale(test.scale) 218 | 219 | s := z.String() 220 | if s != test.out { 221 | t.Errorf("#%da got %s; want %s", i, s, test.out) 222 | } 223 | 224 | s = fmt.Sprintf("%d", z) 225 | if s != test.out { 226 | t.Errorf("#%db got %s; want %s", i, s, test.out) 227 | } 228 | } 229 | } 230 | 231 | func TestDecSetString(t *testing.T) { 232 | tmp := new(inf.Dec) 233 | for i, test := range decStringTests { 234 | if test.scale < 0 { 235 | // SetString only supports scale >= 0 236 | continue 237 | } 238 | // initialize to a non-zero value so that issues with parsing 239 | // 0 are detected 240 | tmp.Set(inf.NewDec(1234567890, 123)) 241 | n1, ok1 := new(inf.Dec).SetString(test.in) 242 | n2, ok2 := tmp.SetString(test.in) 243 | expected := inf.NewDec(test.val, test.scale) 244 | if ok1 != test.ok || ok2 != test.ok { 245 | t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok) 246 | continue 247 | } 248 | if !ok1 { 249 | if n1 != nil { 250 | t.Errorf("#%d (input '%s') n1 != nil", i, test.in) 251 | } 252 | continue 253 | } 254 | if !ok2 { 255 | if n2 != nil { 256 | t.Errorf("#%d (input '%s') n2 != nil", i, test.in) 257 | } 258 | continue 259 | } 260 | 261 | if n1.Cmp(expected) != 0 { 262 | t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val) 263 | } 264 | if n2.Cmp(expected) != 0 { 265 | t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val) 266 | } 267 | } 268 | } 269 | 270 | func TestDecScan(t *testing.T) { 271 | tmp := new(inf.Dec) 272 | for i, test := range decStringTests { 273 | if test.scale < 0 { 274 | // SetString only supports scale >= 0 275 | continue 276 | } 277 | // initialize to a non-zero value so that issues with parsing 278 | // 0 are detected 279 | tmp.Set(inf.NewDec(1234567890, 123)) 280 | n1, n2 := new(inf.Dec), tmp 281 | nn1, err1 := fmt.Sscan(test.in, n1) 282 | nn2, err2 := fmt.Sscan(test.in, n2) 283 | if !test.scanOk { 284 | if err1 == nil || err2 == nil { 285 | t.Errorf("#%d (input '%s') ok incorrect, should be %t", i, test.in, test.scanOk) 286 | } 287 | continue 288 | } 289 | expected := inf.NewDec(test.val, test.scale) 290 | if nn1 != 1 || err1 != nil || nn2 != 1 || err2 != nil { 291 | t.Errorf("#%d (input '%s') error %d %v, %d %v", i, test.in, nn1, err1, nn2, err2) 292 | continue 293 | } 294 | if n1.Cmp(expected) != 0 { 295 | t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val) 296 | } 297 | if n2.Cmp(expected) != 0 { 298 | t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val) 299 | } 300 | } 301 | } 302 | 303 | var decScanNextTests = []struct { 304 | in string 305 | ok bool 306 | next rune 307 | }{ 308 | {"", false, 0}, 309 | {"a", false, 'a'}, 310 | {"z", false, 'z'}, 311 | {"+", false, 0}, 312 | {"-", false, 0}, 313 | {"g", false, 'g'}, 314 | {".", false, 0}, 315 | {".-0", false, '-'}, 316 | {".+0", false, '+'}, 317 | {"0b", true, 'b'}, 318 | {"0x", true, 'x'}, 319 | {"0xg", true, 'x'}, 320 | {"0.0g", true, 'g'}, 321 | } 322 | 323 | func TestDecScanNext(t *testing.T) { 324 | for i, test := range decScanNextTests { 325 | rdr := strings.NewReader(test.in) 326 | n1 := new(inf.Dec) 327 | nn1, _ := fmt.Fscan(rdr, n1) 328 | if (test.ok && nn1 == 0) || (!test.ok && nn1 > 0) { 329 | t.Errorf("#%d (input '%s') ok incorrect should be %t", i, test.in, test.ok) 330 | continue 331 | } 332 | r := rune(0) 333 | nn2, err := fmt.Fscanf(rdr, "%c", &r) 334 | if test.next != r { 335 | t.Errorf("#%d (input '%s') next incorrect, got %c should be %c, %d, %v", i, test.in, r, test.next, nn2, err) 336 | } 337 | } 338 | } 339 | 340 | var decGobEncodingTests = []string{ 341 | "0", 342 | "1", 343 | "2", 344 | "10", 345 | "42", 346 | "1234567890", 347 | "298472983472983471903246121093472394872319615612417471234712061", 348 | } 349 | 350 | func TestDecGobEncoding(t *testing.T) { 351 | var medium bytes.Buffer 352 | enc := gob.NewEncoder(&medium) 353 | dec := gob.NewDecoder(&medium) 354 | for i, test := range decGobEncodingTests { 355 | for j := 0; j < 2; j++ { 356 | for k := inf.Scale(-5); k <= 5; k++ { 357 | medium.Reset() // empty buffer for each test case (in case of failures) 358 | stest := test 359 | if j != 0 { 360 | // negative numbers 361 | stest = "-" + test 362 | } 363 | var tx inf.Dec 364 | tx.SetString(stest) 365 | tx.SetScale(k) // test with positive, negative, and zero scale 366 | if err := enc.Encode(&tx); err != nil { 367 | t.Errorf("#%d%c: encoding failed: %s", i, 'a'+j, err) 368 | } 369 | var rx inf.Dec 370 | if err := dec.Decode(&rx); err != nil { 371 | t.Errorf("#%d%c: decoding failed: %s", i, 'a'+j, err) 372 | } 373 | if rx.Cmp(&tx) != 0 { 374 | t.Errorf("#%d%c: transmission failed: got %s want %s", i, 'a'+j, &rx, &tx) 375 | } 376 | } 377 | } 378 | } 379 | } 380 | -------------------------------------------------------------------------------- /example_test.go: -------------------------------------------------------------------------------- 1 | package inf_test 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | import "gopkg.in/inf.v0" 9 | 10 | func ExampleDec_SetString() { 11 | d := new(inf.Dec) 12 | d.SetString("012345.67890") // decimal; leading 0 ignored; trailing 0 kept 13 | fmt.Println(d) 14 | // Output: 12345.67890 15 | } 16 | 17 | func ExampleDec_Scan() { 18 | // The Scan function is rarely used directly; 19 | // the fmt package recognizes it as an implementation of fmt.Scanner. 20 | d := new(inf.Dec) 21 | _, err := fmt.Sscan("184467440.73709551617", d) 22 | if err != nil { 23 | log.Println("error scanning value:", err) 24 | } else { 25 | fmt.Println(d) 26 | } 27 | // Output: 184467440.73709551617 28 | } 29 | 30 | func ExampleDec_QuoRound_scale2RoundDown() { 31 | // 10 / 3 is an infinite decimal; it has no exact Dec representation 32 | x, y := inf.NewDec(10, 0), inf.NewDec(3, 0) 33 | // use 2 digits beyond the decimal point, round towards 0 34 | z := new(inf.Dec).QuoRound(x, y, 2, inf.RoundDown) 35 | fmt.Println(z) 36 | // Output: 3.33 37 | } 38 | 39 | func ExampleDec_QuoRound_scale2RoundCeil() { 40 | // -42 / 400 is an finite decimal with 3 digits beyond the decimal point 41 | x, y := inf.NewDec(-42, 0), inf.NewDec(400, 0) 42 | // use 2 digits beyond decimal point, round towards positive infinity 43 | z := new(inf.Dec).QuoRound(x, y, 2, inf.RoundCeil) 44 | fmt.Println(z) 45 | // Output: -0.10 46 | } 47 | 48 | func ExampleDec_QuoExact_ok() { 49 | // 1 / 25 is a finite decimal; it has exact Dec representation 50 | x, y := inf.NewDec(1, 0), inf.NewDec(25, 0) 51 | z := new(inf.Dec).QuoExact(x, y) 52 | fmt.Println(z) 53 | // Output: 0.04 54 | } 55 | 56 | func ExampleDec_QuoExact_fail() { 57 | // 1 / 3 is an infinite decimal; it has no exact Dec representation 58 | x, y := inf.NewDec(1, 0), inf.NewDec(3, 0) 59 | z := new(inf.Dec).QuoExact(x, y) 60 | fmt.Println(z) 61 | // Output: 62 | } 63 | -------------------------------------------------------------------------------- /rounder.go: -------------------------------------------------------------------------------- 1 | package inf 2 | 3 | import ( 4 | "math/big" 5 | ) 6 | 7 | // Rounder represents a method for rounding the (possibly infinite decimal) 8 | // result of a division to a finite Dec. It is used by Dec.Round() and 9 | // Dec.Quo(). 10 | // 11 | // See the Example for results of using each Rounder with some sample values. 12 | // 13 | type Rounder rounder 14 | 15 | // See http://speleotrove.com/decimal/damodel.html#refround for more detailed 16 | // definitions of these rounding modes. 17 | var ( 18 | RoundDown Rounder // towards 0 19 | RoundUp Rounder // away from 0 20 | RoundFloor Rounder // towards -infinity 21 | RoundCeil Rounder // towards +infinity 22 | RoundHalfDown Rounder // to nearest; towards 0 if same distance 23 | RoundHalfUp Rounder // to nearest; away from 0 if same distance 24 | RoundHalfEven Rounder // to nearest; even last digit if same distance 25 | ) 26 | 27 | // RoundExact is to be used in the case when rounding is not necessary. 28 | // When used with Quo or Round, it returns the result verbatim when it can be 29 | // expressed exactly with the given precision, and it returns nil otherwise. 30 | // QuoExact is a shorthand for using Quo with RoundExact. 31 | var RoundExact Rounder 32 | 33 | type rounder interface { 34 | 35 | // When UseRemainder() returns true, the Round() method is passed the 36 | // remainder of the division, expressed as the numerator and denominator of 37 | // a rational. 38 | UseRemainder() bool 39 | 40 | // Round sets the rounded value of a quotient to z, and returns z. 41 | // quo is rounded down (truncated towards zero) to the scale obtained from 42 | // the Scaler in Quo(). 43 | // 44 | // When the remainder is not used, remNum and remDen are nil. 45 | // When used, the remainder is normalized between -1 and 1; that is: 46 | // 47 | // -|remDen| < remNum < |remDen| 48 | // 49 | // remDen has the same sign as y, and remNum is zero or has the same sign 50 | // as x. 51 | Round(z, quo *Dec, remNum, remDen *big.Int) *Dec 52 | } 53 | 54 | type rndr struct { 55 | useRem bool 56 | round func(z, quo *Dec, remNum, remDen *big.Int) *Dec 57 | } 58 | 59 | func (r rndr) UseRemainder() bool { 60 | return r.useRem 61 | } 62 | 63 | func (r rndr) Round(z, quo *Dec, remNum, remDen *big.Int) *Dec { 64 | return r.round(z, quo, remNum, remDen) 65 | } 66 | 67 | var intSign = []*big.Int{big.NewInt(-1), big.NewInt(0), big.NewInt(1)} 68 | 69 | func roundHalf(f func(c int, odd uint) (roundUp bool)) func(z, q *Dec, rA, rB *big.Int) *Dec { 70 | return func(z, q *Dec, rA, rB *big.Int) *Dec { 71 | z.Set(q) 72 | brA, brB := rA.BitLen(), rB.BitLen() 73 | if brA < brB-1 { 74 | // brA < brB-1 => |rA| < |rB/2| 75 | return z 76 | } 77 | roundUp := false 78 | srA, srB := rA.Sign(), rB.Sign() 79 | s := srA * srB 80 | if brA == brB-1 { 81 | rA2 := new(big.Int).Lsh(rA, 1) 82 | if s < 0 { 83 | rA2.Neg(rA2) 84 | } 85 | roundUp = f(rA2.Cmp(rB)*srB, z.UnscaledBig().Bit(0)) 86 | } else { 87 | // brA > brB-1 => |rA| > |rB/2| 88 | roundUp = true 89 | } 90 | if roundUp { 91 | z.UnscaledBig().Add(z.UnscaledBig(), intSign[s+1]) 92 | } 93 | return z 94 | } 95 | } 96 | 97 | func init() { 98 | RoundExact = rndr{true, 99 | func(z, q *Dec, rA, rB *big.Int) *Dec { 100 | if rA.Sign() != 0 { 101 | return nil 102 | } 103 | return z.Set(q) 104 | }} 105 | RoundDown = rndr{false, 106 | func(z, q *Dec, rA, rB *big.Int) *Dec { 107 | return z.Set(q) 108 | }} 109 | RoundUp = rndr{true, 110 | func(z, q *Dec, rA, rB *big.Int) *Dec { 111 | z.Set(q) 112 | if rA.Sign() != 0 { 113 | z.UnscaledBig().Add(z.UnscaledBig(), intSign[rA.Sign()*rB.Sign()+1]) 114 | } 115 | return z 116 | }} 117 | RoundFloor = rndr{true, 118 | func(z, q *Dec, rA, rB *big.Int) *Dec { 119 | z.Set(q) 120 | if rA.Sign()*rB.Sign() < 0 { 121 | z.UnscaledBig().Add(z.UnscaledBig(), intSign[0]) 122 | } 123 | return z 124 | }} 125 | RoundCeil = rndr{true, 126 | func(z, q *Dec, rA, rB *big.Int) *Dec { 127 | z.Set(q) 128 | if rA.Sign()*rB.Sign() > 0 { 129 | z.UnscaledBig().Add(z.UnscaledBig(), intSign[2]) 130 | } 131 | return z 132 | }} 133 | RoundHalfDown = rndr{true, roundHalf( 134 | func(c int, odd uint) bool { 135 | return c > 0 136 | })} 137 | RoundHalfUp = rndr{true, roundHalf( 138 | func(c int, odd uint) bool { 139 | return c >= 0 140 | })} 141 | RoundHalfEven = rndr{true, roundHalf( 142 | func(c int, odd uint) bool { 143 | return c > 0 || c == 0 && odd == 1 144 | })} 145 | } 146 | -------------------------------------------------------------------------------- /rounder_example_test.go: -------------------------------------------------------------------------------- 1 | package inf_test 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "text/tabwriter" 7 | 8 | "gopkg.in/inf.v0" 9 | ) 10 | 11 | // This example displays the results of Dec.Round with each of the Rounders. 12 | // 13 | func ExampleRounder() { 14 | var vals = []struct { 15 | x string 16 | s inf.Scale 17 | }{ 18 | {"-0.18", 1}, {"-0.15", 1}, {"-0.12", 1}, {"-0.10", 1}, 19 | {"-0.08", 1}, {"-0.05", 1}, {"-0.02", 1}, {"0.00", 1}, 20 | {"0.02", 1}, {"0.05", 1}, {"0.08", 1}, {"0.10", 1}, 21 | {"0.12", 1}, {"0.15", 1}, {"0.18", 1}, 22 | } 23 | 24 | var rounders = []struct { 25 | name string 26 | rounder inf.Rounder 27 | }{ 28 | {"RoundDown", inf.RoundDown}, {"RoundUp", inf.RoundUp}, 29 | {"RoundCeil", inf.RoundCeil}, {"RoundFloor", inf.RoundFloor}, 30 | {"RoundHalfDown", inf.RoundHalfDown}, {"RoundHalfUp", inf.RoundHalfUp}, 31 | {"RoundHalfEven", inf.RoundHalfEven}, {"RoundExact", inf.RoundExact}, 32 | } 33 | 34 | fmt.Println("The results of new(inf.Dec).Round(x, s, inf.RoundXXX):") 35 | fmt.Println() 36 | w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.AlignRight) 37 | fmt.Fprint(w, "x\ts\t|\t") 38 | for _, r := range rounders { 39 | fmt.Fprintf(w, "%s\t", r.name[5:]) 40 | } 41 | fmt.Fprintln(w) 42 | for _, v := range vals { 43 | fmt.Fprintf(w, "%s\t%d\t|\t", v.x, v.s) 44 | for _, r := range rounders { 45 | x, _ := new(inf.Dec).SetString(v.x) 46 | z := new(inf.Dec).Round(x, v.s, r.rounder) 47 | fmt.Fprintf(w, "%d\t", z) 48 | } 49 | fmt.Fprintln(w) 50 | } 51 | w.Flush() 52 | 53 | // Output: 54 | // The results of new(inf.Dec).Round(x, s, inf.RoundXXX): 55 | // 56 | // x s | Down Up Ceil Floor HalfDown HalfUp HalfEven Exact 57 | // -0.18 1 | -0.1 -0.2 -0.1 -0.2 -0.2 -0.2 -0.2 58 | // -0.15 1 | -0.1 -0.2 -0.1 -0.2 -0.1 -0.2 -0.2 59 | // -0.12 1 | -0.1 -0.2 -0.1 -0.2 -0.1 -0.1 -0.1 60 | // -0.10 1 | -0.1 -0.1 -0.1 -0.1 -0.1 -0.1 -0.1 -0.1 61 | // -0.08 1 | 0.0 -0.1 0.0 -0.1 -0.1 -0.1 -0.1 62 | // -0.05 1 | 0.0 -0.1 0.0 -0.1 0.0 -0.1 0.0 63 | // -0.02 1 | 0.0 -0.1 0.0 -0.1 0.0 0.0 0.0 64 | // 0.00 1 | 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 65 | // 0.02 1 | 0.0 0.1 0.1 0.0 0.0 0.0 0.0 66 | // 0.05 1 | 0.0 0.1 0.1 0.0 0.0 0.1 0.0 67 | // 0.08 1 | 0.0 0.1 0.1 0.0 0.1 0.1 0.1 68 | // 0.10 1 | 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 69 | // 0.12 1 | 0.1 0.2 0.2 0.1 0.1 0.1 0.1 70 | // 0.15 1 | 0.1 0.2 0.2 0.1 0.1 0.2 0.2 71 | // 0.18 1 | 0.1 0.2 0.2 0.1 0.2 0.2 0.2 72 | 73 | } 74 | -------------------------------------------------------------------------------- /rounder_test.go: -------------------------------------------------------------------------------- 1 | package inf_test 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | 7 | "gopkg.in/inf.v0" 8 | ) 9 | 10 | var decRounderInputs = [...]struct { 11 | quo *inf.Dec 12 | rA, rB *big.Int 13 | }{ 14 | // examples from go language spec 15 | {inf.NewDec(1, 0), big.NewInt(2), big.NewInt(3)}, // 5 / 3 16 | {inf.NewDec(-1, 0), big.NewInt(-2), big.NewInt(3)}, // -5 / 3 17 | {inf.NewDec(-1, 0), big.NewInt(2), big.NewInt(-3)}, // 5 / -3 18 | {inf.NewDec(1, 0), big.NewInt(-2), big.NewInt(-3)}, // -5 / -3 19 | // examples from godoc 20 | {inf.NewDec(-1, 1), big.NewInt(-8), big.NewInt(10)}, 21 | {inf.NewDec(-1, 1), big.NewInt(-5), big.NewInt(10)}, 22 | {inf.NewDec(-1, 1), big.NewInt(-2), big.NewInt(10)}, 23 | {inf.NewDec(0, 1), big.NewInt(-8), big.NewInt(10)}, 24 | {inf.NewDec(0, 1), big.NewInt(-5), big.NewInt(10)}, 25 | {inf.NewDec(0, 1), big.NewInt(-2), big.NewInt(10)}, 26 | {inf.NewDec(0, 1), big.NewInt(0), big.NewInt(1)}, 27 | {inf.NewDec(0, 1), big.NewInt(2), big.NewInt(10)}, 28 | {inf.NewDec(0, 1), big.NewInt(5), big.NewInt(10)}, 29 | {inf.NewDec(0, 1), big.NewInt(8), big.NewInt(10)}, 30 | {inf.NewDec(1, 1), big.NewInt(2), big.NewInt(10)}, 31 | {inf.NewDec(1, 1), big.NewInt(5), big.NewInt(10)}, 32 | {inf.NewDec(1, 1), big.NewInt(8), big.NewInt(10)}, 33 | } 34 | 35 | var decRounderResults = [...]struct { 36 | rounder inf.Rounder 37 | results [len(decRounderInputs)]*inf.Dec 38 | }{ 39 | {inf.RoundExact, [...]*inf.Dec{nil, nil, nil, nil, 40 | nil, nil, nil, nil, nil, nil, 41 | inf.NewDec(0, 1), nil, nil, nil, nil, nil, nil}}, 42 | {inf.RoundDown, [...]*inf.Dec{ 43 | inf.NewDec(1, 0), inf.NewDec(-1, 0), inf.NewDec(-1, 0), inf.NewDec(1, 0), 44 | inf.NewDec(-1, 1), inf.NewDec(-1, 1), inf.NewDec(-1, 1), 45 | inf.NewDec(0, 1), inf.NewDec(0, 1), inf.NewDec(0, 1), 46 | inf.NewDec(0, 1), 47 | inf.NewDec(0, 1), inf.NewDec(0, 1), inf.NewDec(0, 1), 48 | inf.NewDec(1, 1), inf.NewDec(1, 1), inf.NewDec(1, 1)}}, 49 | {inf.RoundUp, [...]*inf.Dec{ 50 | inf.NewDec(2, 0), inf.NewDec(-2, 0), inf.NewDec(-2, 0), inf.NewDec(2, 0), 51 | inf.NewDec(-2, 1), inf.NewDec(-2, 1), inf.NewDec(-2, 1), 52 | inf.NewDec(-1, 1), inf.NewDec(-1, 1), inf.NewDec(-1, 1), 53 | inf.NewDec(0, 1), 54 | inf.NewDec(1, 1), inf.NewDec(1, 1), inf.NewDec(1, 1), 55 | inf.NewDec(2, 1), inf.NewDec(2, 1), inf.NewDec(2, 1)}}, 56 | {inf.RoundHalfDown, [...]*inf.Dec{ 57 | inf.NewDec(2, 0), inf.NewDec(-2, 0), inf.NewDec(-2, 0), inf.NewDec(2, 0), 58 | inf.NewDec(-2, 1), inf.NewDec(-1, 1), inf.NewDec(-1, 1), 59 | inf.NewDec(-1, 1), inf.NewDec(0, 1), inf.NewDec(0, 1), 60 | inf.NewDec(0, 1), 61 | inf.NewDec(0, 1), inf.NewDec(0, 1), inf.NewDec(1, 1), 62 | inf.NewDec(1, 1), inf.NewDec(1, 1), inf.NewDec(2, 1)}}, 63 | {inf.RoundHalfUp, [...]*inf.Dec{ 64 | inf.NewDec(2, 0), inf.NewDec(-2, 0), inf.NewDec(-2, 0), inf.NewDec(2, 0), 65 | inf.NewDec(-2, 1), inf.NewDec(-2, 1), inf.NewDec(-1, 1), 66 | inf.NewDec(-1, 1), inf.NewDec(-1, 1), inf.NewDec(0, 1), 67 | inf.NewDec(0, 1), 68 | inf.NewDec(0, 1), inf.NewDec(1, 1), inf.NewDec(1, 1), 69 | inf.NewDec(1, 1), inf.NewDec(2, 1), inf.NewDec(2, 1)}}, 70 | {inf.RoundHalfEven, [...]*inf.Dec{ 71 | inf.NewDec(2, 0), inf.NewDec(-2, 0), inf.NewDec(-2, 0), inf.NewDec(2, 0), 72 | inf.NewDec(-2, 1), inf.NewDec(-2, 1), inf.NewDec(-1, 1), 73 | inf.NewDec(-1, 1), inf.NewDec(0, 1), inf.NewDec(0, 1), 74 | inf.NewDec(0, 1), 75 | inf.NewDec(0, 1), inf.NewDec(0, 1), inf.NewDec(1, 1), 76 | inf.NewDec(1, 1), inf.NewDec(2, 1), inf.NewDec(2, 1)}}, 77 | {inf.RoundFloor, [...]*inf.Dec{ 78 | inf.NewDec(1, 0), inf.NewDec(-2, 0), inf.NewDec(-2, 0), inf.NewDec(1, 0), 79 | inf.NewDec(-2, 1), inf.NewDec(-2, 1), inf.NewDec(-2, 1), 80 | inf.NewDec(-1, 1), inf.NewDec(-1, 1), inf.NewDec(-1, 1), 81 | inf.NewDec(0, 1), 82 | inf.NewDec(0, 1), inf.NewDec(0, 1), inf.NewDec(0, 1), 83 | inf.NewDec(1, 1), inf.NewDec(1, 1), inf.NewDec(1, 1)}}, 84 | {inf.RoundCeil, [...]*inf.Dec{ 85 | inf.NewDec(2, 0), inf.NewDec(-1, 0), inf.NewDec(-1, 0), inf.NewDec(2, 0), 86 | inf.NewDec(-1, 1), inf.NewDec(-1, 1), inf.NewDec(-1, 1), 87 | inf.NewDec(0, 1), inf.NewDec(0, 1), inf.NewDec(0, 1), 88 | inf.NewDec(0, 1), 89 | inf.NewDec(1, 1), inf.NewDec(1, 1), inf.NewDec(1, 1), 90 | inf.NewDec(2, 1), inf.NewDec(2, 1), inf.NewDec(2, 1)}}, 91 | } 92 | 93 | func TestDecRounders(t *testing.T) { 94 | for i, a := range decRounderResults { 95 | for j, input := range decRounderInputs { 96 | q := new(inf.Dec).Set(input.quo) 97 | rA, rB := new(big.Int).Set(input.rA), new(big.Int).Set(input.rB) 98 | res := a.rounder.Round(new(inf.Dec), q, rA, rB) 99 | if a.results[j] == nil && res == nil { 100 | continue 101 | } 102 | if (a.results[j] == nil && res != nil) || 103 | (a.results[j] != nil && res == nil) || 104 | a.results[j].Cmp(res) != 0 { 105 | t.Errorf("#%d,%d Rounder got %v; expected %v", i, j, res, a.results[j]) 106 | } 107 | } 108 | } 109 | } 110 | --------------------------------------------------------------------------------