├── .github └── workflows │ └── go.yml ├── LICENSE ├── README.md ├── bench_test.go ├── bigint.go ├── bigint_go1.14_test.go ├── bigint_go1.15.go ├── bigint_go1.15_test.go ├── bigint_test.go ├── condition.go ├── const.go ├── const_test.go ├── context.go ├── decimal.go ├── decimal_test.go ├── decomposer.go ├── decomposer_test.go ├── doc.go ├── error.go ├── error_test.go ├── example_test.go ├── form_string.go ├── format.go ├── gda_test.go ├── go.mod ├── go.sum ├── loop.go ├── round.go ├── sql_test.go ├── table.go ├── table_test.go └── testdata ├── abs.decTest ├── add.decTest ├── base.decTest ├── compare.decTest ├── comparetotal.decTest ├── cuberoot-apd.decTest ├── divide.decTest ├── divideint.decTest ├── exp.decTest ├── ln.decTest ├── log10.decTest ├── minus.decTest ├── multiply.decTest ├── plus.decTest ├── power.decTest ├── powersqrt.decTest ├── quantize.decTest ├── randoms.decTest ├── reduce.decTest ├── remainder.decTest ├── rounding.decTest ├── squareroot.decTest ├── subtract.decTest ├── tointegral.decTest └── tointegralx.decTest /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | strategy: 16 | matrix: 17 | arch: 18 | - x64 19 | - armv7 20 | - aarch64 21 | go: 22 | - '1.15' 23 | - '1.16' 24 | - '1.17' 25 | - '1.18' 26 | - '1.19' 27 | - '1.20' 28 | - '1.21' 29 | - '1.22' 30 | - '1.23' 31 | 32 | steps: 33 | - uses: actions/checkout@v2 34 | 35 | - name: Set up Go 36 | uses: actions/setup-go@v2 37 | with: 38 | go-version: '${{ matrix.go }}' 39 | 40 | - name: 'Build' 41 | if: ${{ matrix.arch == 'x64' }} 42 | run: go build -v ./... 43 | 44 | - name: 'Test' 45 | if: ${{ matrix.arch == 'x64' }} 46 | run: go test -v ./... 47 | 48 | - name: 'TestRace' 49 | if: ${{ matrix.arch == 'x64' }} 50 | run: go test -race -v ./... 51 | 52 | - name: 'Bench' 53 | if: ${{ matrix.arch == 'x64' }} 54 | run: go test -run=- -bench=. -benchtime=1x -v ./... 55 | 56 | - name: 'BenchRace' 57 | if: ${{ matrix.arch == 'x64' }} 58 | run: go test -run=- -bench=. -benchtime=1x -race -v ./... 59 | 60 | - name: 'Vet' 61 | if: ${{ matrix.arch == 'x64' }} 62 | # -unsafeptr=false is needed because of the noescape function in bigint.go. 63 | run: go vet -unsafeptr=false ./... 64 | 65 | - name: 'Staticcheck' 66 | # staticcheck requires go1.22. 67 | if: ${{ matrix.arch == 'x64' && matrix.go >= '1.22' }} 68 | run: | 69 | go install honnef.co/go/tools/cmd/staticcheck@v0.5.0 70 | staticcheck ./... 71 | 72 | - name: 'GCAssert' 73 | # Only run gcassert on the latest versions of Go. Inlining heuristics 74 | # change from version to version. 75 | if: ${{ matrix.arch == 'x64' && matrix.go >= '1.18' }} 76 | run: | 77 | go install github.com/jordanlewis/gcassert/cmd/gcassert@7b67d223 78 | gcassert ./... 79 | 80 | - name: 'BuildTest for armv7' 81 | if: ${{ matrix.arch == 'armv7' }} 82 | env: 83 | GOARCH: arm 84 | GOARM: 7 85 | run: go test -c ./... 86 | 87 | - name: 'BuildTest for aarch64' 88 | if: ${{ matrix.arch == 'aarch64' }} 89 | env: 90 | GOARCH: arm64 91 | run: go test -c ./... 92 | 93 | - name: 'Test and Bench on ${{ matrix.arch }}' 94 | # arch != 'x64': we already tested on x86 above. 95 | # go != '1.13': go1.13 + arm is significantly slower, so don't run test suite. 96 | if: ${{ matrix.arch != 'x64' && matrix.go != '1.13' }} 97 | uses: uraimo/run-on-arch-action@v2.1.1 98 | with: 99 | arch: ${{ matrix.arch }} 100 | distro: ubuntu20.04 101 | dockerRunArgs: --mount type=bind,source="$(pwd)",target=/checkout,readonly 102 | run: | 103 | find /checkout -name '*.test' -type f -executable -print0 | xargs -0 -I '{}' sh -c '{} -test.run=. -test.bench=. -test.benchtime=1x -test.v' 104 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # apd 2 | 3 | apd is an arbitrary-precision decimal package for Go. 4 | 5 | `apd` implements much of the decimal specification from the [General Decimal Arithmetic](http://speleotrove.com/decimal/) description. This is the same specification implemented by [python’s decimal module](https://docs.python.org/2/library/decimal.html) and GCC’s decimal extension. 6 | 7 | ## Features 8 | 9 | - **Panic-free operation**. The `math/big` types don’t return errors, and instead panic under some conditions that are documented. This requires users to validate the inputs before using them. Meanwhile, we’d like our decimal operations to have more failure modes and more input requirements than the `math/big` types, so using that API would be difficult. `apd` instead returns errors when needed. 10 | - **Support for standard functions**. `sqrt`, `ln`, `pow`, etc. 11 | - **Accurate and configurable precision**. Operations will use enough internal precision to produce a correct result at the requested precision. Precision is set by a "context" structure that accompanies the function arguments, as discussed in the next section. 12 | - **Good performance**. Operations will either be fast enough or will produce an error if they will be slow. This prevents edge-case operations from consuming lots of CPU or memory. 13 | - **Condition flags and traps**. All operations will report whether their result is exact, is rounded, is over- or under-flowed, is [subnormal](https://en.wikipedia.org/wiki/Denormal_number), or is some other condition. `apd` supports traps which will trigger an error on any of these conditions. This makes it possible to guarantee exactness in computations, if needed. 14 | 15 | `apd` has three main types. 16 | 17 | The first is [`BigInt`](https://godoc.org/github.com/cockroachdb/apd#BigInt) which is a wrapper around `big.Int` that exposes an identical API while reducing memory allocations. `BigInt` does so by using an inline array to back the `big.Int`'s variable-length value when the integer's absolute value is sufficiently small. `BigInt` also contains fast-paths that allow it to perform basic arithmetic directly on this inline array, only falling back to `big.Int` when the arithmetic gets complex or takes place on large values. 18 | 19 | The second is [`Decimal`](https://godoc.org/github.com/cockroachdb/apd#Decimal) which holds the values of decimals. It is simple and uses a `BigInt` with an exponent to describe values. Most operations on `Decimal`s can’t produce errors as they work directly on the underlying `big.Int`. Notably, however, there are no arithmetic operations on `Decimal`s. 20 | 21 | The third main type is [`Context`](https://godoc.org/github.com/cockroachdb/apd#Context), which is where all arithmetic operations are defined. A `Context` describes the precision, range, and some other restrictions during operations. These operations can all produce failures, and so return errors. 22 | 23 | `Context` operations, in addition to errors, return a [`Condition`](https://godoc.org/github.com/cockroachdb/apd#Condition), which is a bitfield of flags that occurred during an operation. These include overflow, underflow, inexact, rounded, and others. The `Traps` field of a `Context` can be set which will produce an error if the corresponding flag occurs. An example of this is given below. 24 | 25 | See the [examples](https://godoc.org/github.com/cockroachdb/apd#pkg-examples) for some operations that were previously difficult to perform in Go. 26 | 27 | ## Documentation 28 | https://pkg.go.dev/github.com/cockroachdb/apd/v3?tab=doc 29 | -------------------------------------------------------------------------------- /bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | import ( 18 | "bytes" 19 | "fmt" 20 | "math/rand" 21 | "testing" 22 | ) 23 | 24 | // runBenches benchmarks a given function on random decimals on combinations of 25 | // three parameters: 26 | // 27 | // precision: desired output precision 28 | // inScale: the scale of the input decimal: the absolute value will be between 29 | // 10^inScale and 10^(inScale+1) 30 | // inNumDigits: number of digits in the input decimal; if negative the number 31 | // will be negative and the number of digits are the absolute value. 32 | func runBenches( 33 | b *testing.B, precision, inScale, inNumDigits []int, fn func(*testing.B, *Context, *Decimal), 34 | ) { 35 | for _, p := range precision { 36 | ctx := BaseContext.WithPrecision(uint32(p)) 37 | for _, s := range inScale { 38 | for _, d := range inNumDigits { 39 | numDigits := d 40 | negative := false 41 | if d < 0 { 42 | numDigits = -d 43 | negative = true 44 | } 45 | if numDigits > p { 46 | // Skip cases where we have more digits than the desired precision. 47 | continue 48 | } 49 | 50 | // Generate some random numbers with the given number of digits. 51 | nums := make([]Decimal, 20) 52 | for i := range nums { 53 | var buf bytes.Buffer 54 | if negative { 55 | buf.WriteByte('-') 56 | } 57 | buf.WriteByte('1' + byte(rand.Intn(9))) 58 | for j := 1; j < numDigits; j++ { 59 | buf.WriteByte('0' + byte(rand.Intn(10))) 60 | } 61 | if _, _, err := nums[i].SetString(buf.String()); err != nil { 62 | b.Fatal(err) 63 | } 64 | nums[i].Exponent = int32(s - numDigits) 65 | } 66 | b.Run( 67 | fmt.Sprintf("P%d/S%d/D%d", p, s, d), 68 | func(b *testing.B) { 69 | for i := 0; i <= b.N; i++ { 70 | fn(b, ctx, &nums[i%len(nums)]) 71 | } 72 | }, 73 | ) 74 | } 75 | } 76 | } 77 | } 78 | 79 | func BenchmarkExp(b *testing.B) { 80 | precision := []int{5, 10, 100} 81 | scale := []int{-4, -1, 2} 82 | digits := []int{-100, -10, -2, 2, 10, 100} 83 | runBenches( 84 | b, precision, scale, digits, 85 | func(b *testing.B, ctx *Context, x *Decimal) { 86 | if _, err := ctx.Exp(&Decimal{}, x); err != nil { 87 | b.Fatal(err) 88 | } 89 | }, 90 | ) 91 | } 92 | 93 | func BenchmarkLn(b *testing.B) { 94 | precision := []int{2, 10, 100} 95 | scale := []int{-100, -10, -2, 2, 10, 100} 96 | digits := []int{2, 10, 100} 97 | runBenches( 98 | b, precision, scale, digits, 99 | func(b *testing.B, ctx *Context, x *Decimal) { 100 | if _, err := ctx.Ln(&Decimal{}, x); err != nil { 101 | b.Fatal(err) 102 | } 103 | }, 104 | ) 105 | } 106 | 107 | func BenchmarkDecimalString(b *testing.B) { 108 | rng := rand.New(rand.NewSource(461210934723948)) 109 | corpus := func() []Decimal { 110 | res := make([]Decimal, 8192) 111 | for i := range res { 112 | _, err := res[i].SetFloat64(rng.Float64()) 113 | if err != nil { 114 | b.Fatal(err) 115 | } 116 | } 117 | return res 118 | }() 119 | b.ResetTimer() 120 | b.ReportAllocs() 121 | for i := 0; i < b.N; i++ { 122 | _ = corpus[rng.Intn(len(corpus))].String() 123 | } 124 | } 125 | 126 | func BenchmarkDecimalSetFloat(b *testing.B) { 127 | rng := rand.New(rand.NewSource(461210934723948)) 128 | corpus := func() []float64 { 129 | res := make([]float64, 8192) 130 | for i := range res { 131 | res[i] = rng.ExpFloat64() 132 | } 133 | return res 134 | }() 135 | b.ResetTimer() 136 | b.ReportAllocs() 137 | for i := 0; i < b.N; i++ { 138 | var d Decimal 139 | _, err := d.SetFloat64(corpus[rng.Intn(len(corpus))]) 140 | if err != nil { 141 | b.Fatal(err) 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /bigint_go1.14_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | //go:build go1.14 16 | // +build go1.14 17 | 18 | package apd 19 | 20 | import ( 21 | "testing" 22 | "testing/quick" 23 | ) 24 | 25 | ////////////////////////////////////////////////////////////////////////////////// 26 | // The following tests were copied from the standard library's math/big package // 27 | ////////////////////////////////////////////////////////////////////////////////// 28 | 29 | func checkGcd(aBytes, bBytes []byte) bool { 30 | x := new(BigInt) 31 | y := new(BigInt) 32 | a := new(BigInt).SetBytes(aBytes) 33 | b := new(BigInt).SetBytes(bBytes) 34 | 35 | d := new(BigInt).GCD(x, y, a, b) 36 | x.Mul(x, a) 37 | y.Mul(y, b) 38 | x.Add(x, y) 39 | 40 | return x.Cmp(d) == 0 41 | } 42 | 43 | var gcdTests = []struct { 44 | d, x, y, a, b string 45 | }{ 46 | // a <= 0 || b <= 0 47 | {"0", "0", "0", "0", "0"}, 48 | {"7", "0", "1", "0", "7"}, 49 | {"7", "0", "-1", "0", "-7"}, 50 | {"11", "1", "0", "11", "0"}, 51 | {"7", "-1", "-2", "-77", "35"}, 52 | {"935", "-3", "8", "64515", "24310"}, 53 | {"935", "-3", "-8", "64515", "-24310"}, 54 | {"935", "3", "-8", "-64515", "-24310"}, 55 | 56 | {"1", "-9", "47", "120", "23"}, 57 | {"7", "1", "-2", "77", "35"}, 58 | {"935", "-3", "8", "64515", "24310"}, 59 | {"935000000000000000", "-3", "8", "64515000000000000000", "24310000000000000000"}, 60 | {"1", "-221", "22059940471369027483332068679400581064239780177629666810348940098015901108344", "98920366548084643601728869055592650835572950932266967461790948584315647051443", "991"}, 61 | } 62 | 63 | func testGcd(t *testing.T, d, x, y, a, b *BigInt) { 64 | var X *BigInt 65 | if x != nil { 66 | X = new(BigInt) 67 | } 68 | var Y *BigInt 69 | if y != nil { 70 | Y = new(BigInt) 71 | } 72 | 73 | D := new(BigInt).GCD(X, Y, a, b) 74 | if D.Cmp(d) != 0 { 75 | t.Errorf("GCD(%s, %s, %s, %s): got d = %s, want %s", x, y, a, b, D, d) 76 | } 77 | if x != nil && X.Cmp(x) != 0 { 78 | t.Errorf("GCD(%s, %s, %s, %s): got x = %s, want %s", x, y, a, b, X, x) 79 | } 80 | if y != nil && Y.Cmp(y) != 0 { 81 | t.Errorf("GCD(%s, %s, %s, %s): got y = %s, want %s", x, y, a, b, Y, y) 82 | } 83 | 84 | // check results in presence of aliasing (issue #11284) 85 | a2 := new(BigInt).Set(a) 86 | b2 := new(BigInt).Set(b) 87 | a2.GCD(X, Y, a2, b2) // result is same as 1st argument 88 | if a2.Cmp(d) != 0 { 89 | t.Errorf("aliased z = a GCD(%s, %s, %s, %s): got d = %s, want %s", x, y, a, b, a2, d) 90 | } 91 | if x != nil && X.Cmp(x) != 0 { 92 | t.Errorf("aliased z = a GCD(%s, %s, %s, %s): got x = %s, want %s", x, y, a, b, X, x) 93 | } 94 | if y != nil && Y.Cmp(y) != 0 { 95 | t.Errorf("aliased z = a GCD(%s, %s, %s, %s): got y = %s, want %s", x, y, a, b, Y, y) 96 | } 97 | 98 | a2 = new(BigInt).Set(a) 99 | b2 = new(BigInt).Set(b) 100 | b2.GCD(X, Y, a2, b2) // result is same as 2nd argument 101 | if b2.Cmp(d) != 0 { 102 | t.Errorf("aliased z = b GCD(%s, %s, %s, %s): got d = %s, want %s", x, y, a, b, b2, d) 103 | } 104 | if x != nil && X.Cmp(x) != 0 { 105 | t.Errorf("aliased z = b GCD(%s, %s, %s, %s): got x = %s, want %s", x, y, a, b, X, x) 106 | } 107 | if y != nil && Y.Cmp(y) != 0 { 108 | t.Errorf("aliased z = b GCD(%s, %s, %s, %s): got y = %s, want %s", x, y, a, b, Y, y) 109 | } 110 | 111 | a2 = new(BigInt).Set(a) 112 | b2 = new(BigInt).Set(b) 113 | D = new(BigInt).GCD(a2, b2, a2, b2) // x = a, y = b 114 | if D.Cmp(d) != 0 { 115 | t.Errorf("aliased x = a, y = b GCD(%s, %s, %s, %s): got d = %s, want %s", x, y, a, b, D, d) 116 | } 117 | if x != nil && a2.Cmp(x) != 0 { 118 | t.Errorf("aliased x = a, y = b GCD(%s, %s, %s, %s): got x = %s, want %s", x, y, a, b, a2, x) 119 | } 120 | if y != nil && b2.Cmp(y) != 0 { 121 | t.Errorf("aliased x = a, y = b GCD(%s, %s, %s, %s): got y = %s, want %s", x, y, a, b, b2, y) 122 | } 123 | 124 | a2 = new(BigInt).Set(a) 125 | b2 = new(BigInt).Set(b) 126 | D = new(BigInt).GCD(b2, a2, a2, b2) // x = b, y = a 127 | if D.Cmp(d) != 0 { 128 | t.Errorf("aliased x = b, y = a GCD(%s, %s, %s, %s): got d = %s, want %s", x, y, a, b, D, d) 129 | } 130 | if x != nil && b2.Cmp(x) != 0 { 131 | t.Errorf("aliased x = b, y = a GCD(%s, %s, %s, %s): got x = %s, want %s", x, y, a, b, b2, x) 132 | } 133 | if y != nil && a2.Cmp(y) != 0 { 134 | t.Errorf("aliased x = b, y = a GCD(%s, %s, %s, %s): got y = %s, want %s", x, y, a, b, a2, y) 135 | } 136 | } 137 | 138 | // This was not supported in go1.13. See https://go.dev/doc/go1.14: 139 | // > The GCD method now allows the inputs a and b to be zero or negative. 140 | func TestBigIntGcd(t *testing.T) { 141 | for _, test := range gcdTests { 142 | d, _ := new(BigInt).SetString(test.d, 0) 143 | x, _ := new(BigInt).SetString(test.x, 0) 144 | y, _ := new(BigInt).SetString(test.y, 0) 145 | a, _ := new(BigInt).SetString(test.a, 0) 146 | b, _ := new(BigInt).SetString(test.b, 0) 147 | 148 | testGcd(t, d, nil, nil, a, b) 149 | testGcd(t, d, x, nil, a, b) 150 | testGcd(t, d, nil, y, a, b) 151 | testGcd(t, d, x, y, a, b) 152 | } 153 | 154 | if err := quick.Check(checkGcd, nil); err != nil { 155 | t.Error(err) 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /bigint_go1.15.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | //go:build go1.15 16 | // +build go1.15 17 | 18 | package apd 19 | 20 | import "math/big" 21 | 22 | // FillBytes calls (big.Int).FillBytes. 23 | func (z *BigInt) FillBytes(buf []byte) []byte { 24 | var tmp1 big.Int 25 | return z.inner(&tmp1).FillBytes(buf) 26 | } 27 | -------------------------------------------------------------------------------- /bigint_go1.15_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | //go:build go1.15 16 | // +build go1.15 17 | 18 | package apd 19 | 20 | import ( 21 | "testing" 22 | "testing/quick" 23 | ) 24 | 25 | // TestBigIntMatchesMathBigInt15 is like TestBigIntMatchesMathBigInt, but for 26 | // parts of the shared BigInt/big.Int API that were introduced in go1.15. 27 | func TestBigIntMatchesMathBigInt15(t *testing.T) { 28 | t.Run("FillBytes", func(t *testing.T) { 29 | apd := func(z number) []byte { 30 | return z.toApd(t).FillBytes(make([]byte, len(z))) 31 | } 32 | math := func(z number) []byte { 33 | return z.toMath(t).FillBytes(make([]byte, len(z))) 34 | } 35 | require(t, quick.CheckEqual(apd, math, nil)) 36 | }) 37 | } 38 | 39 | ////////////////////////////////////////////////////////////////////////////////// 40 | // The following tests were copied from the standard library's math/big package // 41 | ////////////////////////////////////////////////////////////////////////////////// 42 | 43 | func TestBigIntFillBytes(t *testing.T) { 44 | checkResult := func(t *testing.T, buf []byte, want *BigInt) { 45 | t.Helper() 46 | got := new(BigInt).SetBytes(buf) 47 | if got.CmpAbs(want) != 0 { 48 | t.Errorf("got 0x%x, want 0x%x: %x", got, want, buf) 49 | } 50 | } 51 | panics := func(f func()) (panic bool) { 52 | defer func() { panic = recover() != nil }() 53 | f() 54 | return 55 | } 56 | 57 | for _, n := range []string{ 58 | "0", 59 | "1000", 60 | "0xffffffff", 61 | "-0xffffffff", 62 | "0xffffffffffffffff", 63 | "0x10000000000000000", 64 | "0xabababababababababababababababababababababababababa", 65 | "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 66 | } { 67 | t.Run(n, func(t *testing.T) { 68 | t.Log(n) 69 | x, ok := new(BigInt).SetString(n, 0) 70 | if !ok { 71 | panic("invalid test entry") 72 | } 73 | 74 | // Perfectly sized buffer. 75 | byteLen := (x.BitLen() + 7) / 8 76 | buf := make([]byte, byteLen) 77 | checkResult(t, x.FillBytes(buf), x) 78 | 79 | // Way larger, checking all bytes get zeroed. 80 | buf = make([]byte, 100) 81 | for i := range buf { 82 | buf[i] = 0xff 83 | } 84 | checkResult(t, x.FillBytes(buf), x) 85 | 86 | // Too small. 87 | if byteLen > 0 { 88 | buf = make([]byte, byteLen-1) 89 | if !panics(func() { x.FillBytes(buf) }) { 90 | t.Errorf("expected panic for small buffer and value %x", x) 91 | } 92 | } 93 | }) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /condition.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | import ( 18 | "errors" 19 | "fmt" 20 | "strings" 21 | ) 22 | 23 | // Condition holds condition flags. 24 | type Condition uint32 25 | 26 | const ( 27 | // SystemOverflow is raised when an exponent is greater than MaxExponent. 28 | SystemOverflow Condition = 1 << iota 29 | // SystemUnderflow is raised when an exponent is less than MinExponent. 30 | SystemUnderflow 31 | // Overflow is raised when the exponent of a result is too large to be 32 | // represented. 33 | Overflow 34 | // Underflow is raised when a result is both subnormal and inexact. 35 | Underflow 36 | // Inexact is raised when a result is not exact (one or more non-zero 37 | // coefficient digits were discarded during rounding). 38 | Inexact 39 | // Subnormal is raised when a result is subnormal (its adjusted exponent is 40 | // less than Emin), before any rounding. 41 | Subnormal 42 | // Rounded is raised when a result has been rounded (that is, some zero or 43 | // non-zero coefficient digits were discarded). 44 | Rounded 45 | // DivisionUndefined is raised when both division operands are 0. 46 | DivisionUndefined 47 | // DivisionByZero is raised when a non-zero dividend is divided by zero. 48 | DivisionByZero 49 | // DivisionImpossible is raised when integer division cannot be exactly 50 | // represented with the given precision. 51 | DivisionImpossible 52 | // InvalidOperation is raised when a result would be undefined or impossible. 53 | InvalidOperation 54 | // Clamped is raised when the exponent of a result has been altered or 55 | // constrained in order to fit the constraints of the Decimal representation. 56 | Clamped 57 | ) 58 | 59 | // Any returns true if any flag is true. 60 | func (r Condition) Any() bool { return r != 0 } 61 | 62 | // SystemOverflow returns true if the SystemOverflow flag is set. 63 | func (r Condition) SystemOverflow() bool { return r&SystemOverflow != 0 } 64 | 65 | // SystemUnderflow returns true if the SystemUnderflow flag is set. 66 | func (r Condition) SystemUnderflow() bool { return r&SystemUnderflow != 0 } 67 | 68 | // Overflow returns true if the Overflow flag is set. 69 | func (r Condition) Overflow() bool { return r&Overflow != 0 } 70 | 71 | // Underflow returns true if the Underflow flag is set. 72 | func (r Condition) Underflow() bool { return r&Underflow != 0 } 73 | 74 | // Inexact returns true if the Inexact flag is set. 75 | func (r Condition) Inexact() bool { return r&Inexact != 0 } 76 | 77 | // Subnormal returns true if the Subnormal flag is set. 78 | func (r Condition) Subnormal() bool { return r&Subnormal != 0 } 79 | 80 | // Rounded returns true if the Rounded flag is set. 81 | func (r Condition) Rounded() bool { return r&Rounded != 0 } 82 | 83 | // DivisionUndefined returns true if the DivisionUndefined flag is set. 84 | func (r Condition) DivisionUndefined() bool { return r&DivisionUndefined != 0 } 85 | 86 | // DivisionByZero returns true if the DivisionByZero flag is set. 87 | func (r Condition) DivisionByZero() bool { return r&DivisionByZero != 0 } 88 | 89 | // DivisionImpossible returns true if the DivisionImpossible flag is set. 90 | func (r Condition) DivisionImpossible() bool { return r&DivisionImpossible != 0 } 91 | 92 | // InvalidOperation returns true if the InvalidOperation flag is set. 93 | func (r Condition) InvalidOperation() bool { return r&InvalidOperation != 0 } 94 | 95 | // Clamped returns true if the Clamped flag is set. 96 | func (r Condition) Clamped() bool { return r&Clamped != 0 } 97 | 98 | // GoError converts r to an error based on the given traps and returns 99 | // r. Traps are the conditions which will trigger an error result if the 100 | // corresponding Flag condition occurred. 101 | func (r Condition) GoError(traps Condition) (Condition, error) { 102 | const ( 103 | systemErrors = SystemOverflow | SystemUnderflow 104 | ) 105 | var err error 106 | if r&systemErrors != 0 { 107 | err = errors.New(errExponentOutOfRangeStr) 108 | } else if t := r & traps; t != 0 { 109 | err = errors.New(t.String()) 110 | } 111 | return r, err 112 | } 113 | 114 | func (r Condition) String() string { 115 | var names []string 116 | for i := Condition(1); r != 0; i <<= 1 { 117 | if r&i == 0 { 118 | continue 119 | } 120 | r ^= i 121 | var s string 122 | switch i { 123 | case SystemOverflow, SystemUnderflow: 124 | continue 125 | case Overflow: 126 | s = "overflow" 127 | case Underflow: 128 | s = "underflow" 129 | case Inexact: 130 | s = "inexact" 131 | case Subnormal: 132 | s = "subnormal" 133 | case Rounded: 134 | s = "rounded" 135 | case DivisionUndefined: 136 | s = "division undefined" 137 | case DivisionByZero: 138 | s = "division by zero" 139 | case DivisionImpossible: 140 | s = "division impossible" 141 | case InvalidOperation: 142 | s = "invalid operation" 143 | case Clamped: 144 | s = "clamped" 145 | default: 146 | panic(fmt.Errorf("unknown condition %d", i)) 147 | } 148 | names = append(names, s) 149 | } 150 | return strings.Join(names, ", ") 151 | } 152 | 153 | // negateOverflowFlags converts Overflow and SystemOverflow flags into their 154 | // equivalent Underflows. 155 | func (r Condition) negateOverflowFlags() Condition { 156 | if r.Overflow() { 157 | // Underflow always also means Subnormal. See GDA definition. 158 | r |= Underflow | Subnormal 159 | r &= ^Overflow 160 | } 161 | if r.SystemOverflow() { 162 | r |= SystemUnderflow 163 | r &= ^SystemOverflow 164 | } 165 | return r 166 | } 167 | -------------------------------------------------------------------------------- /const.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | import "math" 18 | 19 | var ( 20 | bigOne = NewBigInt(1) 21 | bigTwo = NewBigInt(2) 22 | bigFive = NewBigInt(5) 23 | bigTen = NewBigInt(10) 24 | 25 | decimalZero = New(0, 0) 26 | decimalOneEighth = New(125, -3) 27 | decimalHalf = New(5, -1) 28 | decimalOne = New(1, 0) 29 | decimalTwo = New(2, 0) 30 | decimalThree = New(3, 0) 31 | decimalEight = New(8, 0) 32 | 33 | decimalMaxInt64 = New(math.MaxInt64, 0) 34 | decimalMinInt64 = New(math.MinInt64, 0) 35 | 36 | decimalCbrtC1 = makeConst(strCbrtC1) 37 | decimalCbrtC2 = makeConst(strCbrtC2) 38 | decimalCbrtC3 = makeConst(strCbrtC3) 39 | 40 | // ln(10) 41 | decimalLn10 = makeConstWithPrecision(strLn10) 42 | // 1/ln(10) 43 | decimalInvLn10 = makeConstWithPrecision(strInvLn10) 44 | ) 45 | 46 | func makeConst(strVal string) *Decimal { 47 | d := &Decimal{} 48 | _, _, err := d.SetString(strVal) 49 | if err != nil { 50 | panic(err) 51 | } 52 | return d 53 | } 54 | 55 | // constWithPrecision implements a look-up table for a constant, rounded-down to 56 | // various precisions. The point is to avoid doing calculations with all the 57 | // digits of the constant when a smaller precision is required. 58 | type constWithPrecision struct { 59 | unrounded Decimal 60 | vals []Decimal 61 | } 62 | 63 | func makeConstWithPrecision(strVal string) *constWithPrecision { 64 | c := &constWithPrecision{} 65 | if _, _, err := c.unrounded.SetString(strVal); err != nil { 66 | panic(err) 67 | } 68 | // The length of the string might be one higher than the available precision 69 | // (because of the decimal point), but that's ok. 70 | maxPrec := uint32(len(strVal)) 71 | for p := uint32(1); p < maxPrec; p *= 2 { 72 | var d Decimal 73 | 74 | ctx := Context{ 75 | Precision: p, 76 | Rounding: RoundHalfUp, 77 | MaxExponent: MaxExponent, 78 | MinExponent: MinExponent, 79 | } 80 | _, err := ctx.Round(&d, &c.unrounded) 81 | if err != nil { 82 | panic(err) 83 | } 84 | c.vals = append(c.vals, d) 85 | } 86 | return c 87 | } 88 | 89 | // get returns the given constant, rounded down to a precision at least as high 90 | // as the given precision. 91 | func (c *constWithPrecision) get(precision uint32) *Decimal { 92 | i := 0 93 | // Find the smallest precision available that's at least as high as precision, 94 | // i.e. Ceil[ log2(p) ] = 1 + Floor[ log2(p-1) ] 95 | if precision > 1 { 96 | precision-- 97 | i++ 98 | } 99 | for precision >= 16 { 100 | precision /= 16 101 | i += 4 102 | } 103 | for precision >= 2 { 104 | precision /= 2 105 | i++ 106 | } 107 | if i >= len(c.vals) { 108 | return &c.unrounded 109 | } 110 | return &c.vals[i] 111 | } 112 | 113 | const strLn10 = "2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058498078280597511938544450099781311469159346662410718466923101075984383191912922307925037472986509290098803919417026544168163357275557031515961135648465461908970428197633658369837163289821744073660091621778505417792763677311450417821376601110107310423978325218948988175979217986663943195239368559164471182467532456309125287783309636042629821530408745609277607266413547875766162629265682987049579549139549180492090694385807900327630179415031178668620924085379498612649334793548717374516758095370882810674524401058924449764796860751202757241818749893959716431055188481952883307466993178146349300003212003277656541304726218839705967944579434683432183953044148448037013057536742621536755798147704580314136377932362915601281853364984669422614652064599420729171193706024449293580370077189810973625332245483669885055282859661928050984471751985036666808749704969822732202448233430971691111368135884186965493237149969419796878030088504089796185987565798948364452120436982164152929878117429733325886079159125109671875109292484750239305726654462762009230687915181358034777012955936462984123664970233551745861955647724618577173693684046765770478743197805738532718109338834963388130699455693993461010907456160333122479493604553618491233330637047517248712763791409243983318101647378233796922656376820717069358463945316169494117018419381194054164494661112747128197058177832938417422314099300229115023621921867233372683856882735333719251034129307056325444266114297653883018223840910261985828884335874559604530045483707890525784731662837019533922310475275649981192287427897137157132283196410034221242100821806795252766898581809561192083917607210809199234615169525990994737827806481280587927319938934534153201859697110214075422827962982370689417647406422257572124553925261793736524344405605953365915391603125244801493132345724538795243890368392364505078817313597112381453237015084134911223243909276817247496079557991513639828810582857405380006533716555530141963322419180876210182049194926514838926922937079" 114 | 115 | const strInvLn10 = "0.4342944819032518276511289189166050822943970058036665661144537831658646492088707747292249493384317483187061067447663037336416792871589639065692210646628122658521270865686703295933708696588266883311636077384905142844348666768646586085135561482123487653435434357317253835622281395603048646652366095539377356176323431916710991411597894962993512457934926357655469077671082419150479910989674900103277537653570270087328550951731440674697951899513594088040423931518868108402544654089797029863286828762624144013457043546132920600712605104028367125954846287707861998992326748439902348171535934551079475492552482577820679220140931468164467381030560475635720408883383209488996522717494541331791417640247407505788767860971099257547730046048656049515610057985741340272675201439247917970859047931285212493341197329877226463885350226083881626316463883553685501768460295286399391633510647555704050513182342988874882120643595023818902643317711537382203362634416478397146001858396093006317333986134035135741787144971453076492968331392399810608505734816169809280016199523523117237676561989228127013815804248715978344927215947562057179993483814031940166771520104787197582531617951490375597514246570736646439756863149325162498727994852637448791165959219701720662704559284657036462635675733575739369673994570909602526350957193468839951236811356428010958778313759442713049980643798750414472095974872674060160650105375287000491167867133309154761441005054775930890767885596533432190763128353570304854020979941614010807910607498871752495841461303867532086001324486392545573072842386175970677989354844570318359336523016027971626535726514428519866063768635338181954876389161343652374759465663921380736144503683797876824369028804493640496751871720614130731804417180216440993200651069696951247072666224570004229341407923361685302418860272411867806272570337552562870767696632173672454758133339263840130320038598899947332285703494195837691472090608812447825078736711573033931565625157907093245370450744326623349807143038059581776957944070042202545430531910888982754062263600601879152267477788232096025228766762416332296812464502577295040226623627536311798532153780883272326920785980990757434437367248710355853306546581653535157943990070326436222520010336980419843015524524173190520247212241110927324425302930200871037337504867498689117225672067268275246578790446735268575794059983346595878592624978725380185506389602375304294539963737367434680767515249986297676732404903363175488195323680087668648666069282082342536311304939972702858872849086258458687045569244548538607202497396631126372122497538854967981580284810494724140453341192674240839673061167234256843129624666246259542760677182858963306586513950932049023032806357536242804315480658368852257832901530787483141985929074121415344772165398214847619288406571345438798607895199435011532826457742311266817183284968697890904324421005272233475053141625981646457044538901148313760708445483457955728303866473638468537587172210685993933008378534367552699899185150879055911525282664" 116 | 117 | const ( 118 | // Cbrt uses a quadratic polynomial that approximates the cube root 119 | // of x when 0.125 <= x <= 1. This approximation is the starting point 120 | // of the convergence loop. Coefficients are from: 121 | // https://people.freebsd.org/~lstewart/references/apple_tr_kt32_cuberoot.pdf 122 | strCbrtC1 = "-0.46946116" 123 | strCbrtC2 = "1.072302" 124 | strCbrtC3 = "0.3812513" 125 | ) 126 | -------------------------------------------------------------------------------- /const_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | import "testing" 18 | 19 | func TestConstWithPrecision(t *testing.T) { 20 | c := makeConstWithPrecision("123.456789") 21 | expected := []string{ 22 | "1E+2", // 0 23 | "1E+2", // 1 24 | "1.2E+2", // 2 25 | "123.5", "123.5", // 3, 4 26 | "123.45679", "123.45679", "123.45679", "123.45679", // 5..8 27 | "123.456789", "123.456789", "123.456789", // 9+ 28 | } 29 | for i, e := range expected { 30 | if s := c.get(uint32(i)).String(); s != e { 31 | t.Errorf("%d: expected %s, got %s", i, e, s) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /decimal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | import ( 18 | "errors" 19 | "fmt" 20 | "strconv" 21 | "strings" 22 | "unsafe" 23 | 24 | "database/sql/driver" 25 | ) 26 | 27 | // Decimal is an arbitrary-precision decimal. Its value is: 28 | // 29 | // Negative × Coeff × 10**Exponent 30 | // 31 | // Coeff must be positive. If it is negative results may be incorrect and 32 | // apd may panic. 33 | type Decimal struct { 34 | Form Form 35 | Negative bool 36 | Exponent int32 37 | Coeff BigInt 38 | } 39 | 40 | // Form specifies the form of a Decimal. 41 | type Form int8 42 | 43 | const ( 44 | // These constants must be in the following order. CmpTotal assumes that 45 | // the order of these constants reflects the total order on decimals. 46 | 47 | // Finite is the finite form. 48 | Finite Form = iota 49 | // Infinite is the infinite form. 50 | Infinite 51 | // NaNSignaling is the signaling NaN form. It will always raise the 52 | // InvalidOperation condition during an operation. 53 | NaNSignaling 54 | // NaN is the NaN form. 55 | NaN 56 | ) 57 | 58 | var ( 59 | decimalNaN = &Decimal{Form: NaN} 60 | decimalInfinity = &Decimal{Form: Infinite} 61 | ) 62 | 63 | //go:generate stringer -type=Form 64 | 65 | const ( 66 | // TODO(mjibson): MaxExponent is set because both upscale and Round 67 | // perform a calculation of 10^x, where x is an exponent. This is done by 68 | // big.Int.Exp. This restriction could be lifted if better algorithms were 69 | // determined during upscale and Round that don't need to perform Exp. 70 | 71 | // MaxExponent is the highest exponent supported. Exponents near this range will 72 | // perform very slowly (many seconds per operation). 73 | MaxExponent = 100000 74 | // MinExponent is the lowest exponent supported with the same limitations as 75 | // MaxExponent. 76 | MinExponent = -MaxExponent 77 | ) 78 | 79 | // New creates a new decimal with the given coefficient and exponent. 80 | func New(coeff int64, exponent int32) *Decimal { 81 | d := new(Decimal) 82 | d.SetFinite(coeff, exponent) 83 | return d 84 | } 85 | 86 | // NewWithBigInt creates a new decimal with the given coefficient and exponent. 87 | func NewWithBigInt(coeff *BigInt, exponent int32) *Decimal { 88 | d := new(Decimal) 89 | d.Coeff.Set(coeff) 90 | if d.Coeff.Sign() < 0 { 91 | d.Negative = true 92 | d.Coeff.Abs(&d.Coeff) 93 | } 94 | d.Exponent = exponent 95 | return d 96 | } 97 | 98 | func consumePrefix(s, prefix string) (string, bool) { 99 | if strings.HasPrefix(s, prefix) { 100 | return s[len(prefix):], true 101 | } 102 | return s, false 103 | } 104 | 105 | func (d *Decimal) setString(c *Context, s string) (Condition, error) { 106 | orig := s 107 | s, d.Negative = consumePrefix(s, "-") 108 | if !d.Negative { 109 | s, _ = consumePrefix(s, "+") 110 | } 111 | s = strings.ToLower(s) 112 | d.Exponent = 0 113 | d.Coeff.SetInt64(0) 114 | // Until there are no parse errors, leave as NaN. 115 | d.Form = NaN 116 | if strings.HasPrefix(s, "-") || strings.HasPrefix(s, "+") { 117 | return 0, fmt.Errorf("could not parse: %s", orig) 118 | } 119 | switch s { 120 | case "infinity", "inf": 121 | d.Form = Infinite 122 | return 0, nil 123 | } 124 | isNaN := false 125 | s, consumed := consumePrefix(s, "nan") 126 | if consumed { 127 | isNaN = true 128 | } 129 | s, consumed = consumePrefix(s, "snan") 130 | if consumed { 131 | isNaN = true 132 | d.Form = NaNSignaling 133 | } 134 | if isNaN { 135 | if s != "" { 136 | // We ignore these digits, but must verify them. 137 | _, err := strconv.ParseUint(s, 10, 64) 138 | if err != nil { 139 | return 0, fmt.Errorf("parse payload: %s: %w", s, err) 140 | } 141 | } 142 | return 0, nil 143 | } 144 | 145 | exps := make([]int64, 0, 2) 146 | if i := strings.IndexByte(s, 'e'); i >= 0 { 147 | exp, err := strconv.ParseInt(s[i+1:], 10, 32) 148 | if err != nil { 149 | return 0, fmt.Errorf("parse exponent: %s: %w", s[i+1:], err) 150 | } 151 | exps = append(exps, exp) 152 | s = s[:i] 153 | } 154 | if i := strings.IndexByte(s, '.'); i >= 0 { 155 | exp := int64(len(s) - i - 1) 156 | exps = append(exps, -exp) 157 | s = s[:i] + s[i+1:] 158 | } 159 | if _, ok := d.Coeff.SetString(s, 10); !ok { 160 | return 0, fmt.Errorf("parse mantissa: %s", s) 161 | } 162 | // No parse errors, can now flag as finite. 163 | d.Form = Finite 164 | return c.goError(d.setExponent(c, unknownNumDigits, 0, exps...)) 165 | } 166 | 167 | // NewFromString creates a new decimal from s. It has no restrictions on 168 | // exponents or precision. 169 | func NewFromString(s string) (*Decimal, Condition, error) { 170 | return BaseContext.NewFromString(s) 171 | } 172 | 173 | // SetString sets d to s and returns d. It has no restrictions on exponents 174 | // or precision. 175 | func (d *Decimal) SetString(s string) (*Decimal, Condition, error) { 176 | return BaseContext.SetString(d, s) 177 | } 178 | 179 | // NewFromString creates a new decimal from s. The returned Decimal has its 180 | // exponents restricted by the context and its value rounded if it contains more 181 | // digits than the context's precision. 182 | func (c *Context) NewFromString(s string) (*Decimal, Condition, error) { 183 | d := new(Decimal) 184 | return c.SetString(d, s) 185 | } 186 | 187 | // SetString sets d to s and returns d. The returned Decimal has its exponents 188 | // restricted by the context and its value rounded if it contains more digits 189 | // than the context's precision. 190 | func (c *Context) SetString(d *Decimal, s string) (*Decimal, Condition, error) { 191 | res, err := d.setString(c, s) 192 | if err != nil { 193 | return nil, 0, err 194 | } 195 | res |= c.round(d, d) 196 | _, err = c.goError(res) 197 | return d, res, err 198 | } 199 | 200 | // Set sets d's fields to the values of x and returns d. 201 | // 202 | //gcassert:inline 203 | func (d *Decimal) Set(x *Decimal) *Decimal { 204 | if d == x { 205 | return d 206 | } 207 | return d.setSlow(x) 208 | } 209 | 210 | // setSlow is split from Set to allow the aliasing fast-path to be 211 | // inlined in callers. 212 | func (d *Decimal) setSlow(x *Decimal) *Decimal { 213 | d.Form = x.Form 214 | d.Negative = x.Negative 215 | d.Exponent = x.Exponent 216 | d.Coeff.Set(&x.Coeff) 217 | return d 218 | } 219 | 220 | // SetInt64 sets d to x and returns d. 221 | func (d *Decimal) SetInt64(x int64) *Decimal { 222 | return d.SetFinite(x, 0) 223 | } 224 | 225 | // SetFinite sets d to x with exponent e and returns d. 226 | func (d *Decimal) SetFinite(x int64, e int32) *Decimal { 227 | d.setCoefficient(x) 228 | d.Exponent = e 229 | return d 230 | } 231 | 232 | // setCoefficient sets d's coefficient and negative value to x and its Form 233 | // to Finite The exponent is not changed. Since the exponent is not changed 234 | // (and this is thus easy to misuse), this is unexported for internal use only. 235 | func (d *Decimal) setCoefficient(x int64) { 236 | d.Negative = x < 0 237 | d.Coeff.SetInt64(x) 238 | d.Coeff.Abs(&d.Coeff) 239 | d.Form = Finite 240 | } 241 | 242 | // SetFloat64 sets d's Coefficient and Exponent to x and returns d. d will 243 | // hold the exact value of f. 244 | func (d *Decimal) SetFloat64(f float64) (*Decimal, error) { 245 | var buf [32]byte // Avoid most of the allocations in strconv. 246 | _, _, err := d.SetString(string(strconv.AppendFloat(buf[:0], f, 'E', -1, 64))) 247 | return d, err 248 | } 249 | 250 | // Int64 returns the int64 representation of x. If x cannot be represented in an 251 | // int64, an error is returned. 252 | func (d *Decimal) Int64() (int64, error) { 253 | if d.Form != Finite { 254 | return 0, fmt.Errorf("%s is not finite", d.String()) 255 | } 256 | var integ, frac Decimal 257 | d.Modf(&integ, &frac) 258 | if !frac.IsZero() { 259 | return 0, fmt.Errorf("%s: has fractional part", d.String()) 260 | } 261 | var ed ErrDecimal 262 | if integ.Cmp(decimalMaxInt64) > 0 { 263 | return 0, fmt.Errorf("%s: greater than max int64", d.String()) 264 | } 265 | if integ.Cmp(decimalMinInt64) < 0 { 266 | return 0, fmt.Errorf("%s: less than min int64", d.String()) 267 | } 268 | if err := ed.Err(); err != nil { 269 | return 0, err 270 | } 271 | v := integ.Coeff.Int64() 272 | for i := int32(0); i < integ.Exponent; i++ { 273 | v *= 10 274 | } 275 | if d.Negative { 276 | v = -v 277 | } 278 | return v, nil 279 | } 280 | 281 | // Float64 returns the float64 representation of x. This conversion may lose 282 | // data (see strconv.ParseFloat for caveats). 283 | func (d *Decimal) Float64() (float64, error) { 284 | return strconv.ParseFloat(d.String(), 64) 285 | } 286 | 287 | const ( 288 | errExponentOutOfRangeStr = "exponent out of range" 289 | 290 | unknownNumDigits = int64(-1) 291 | ) 292 | 293 | // setExponent sets d's Exponent to the sum of xs. Each value and the sum 294 | // of xs must fit within an int32. An error occurs if the sum is outside of 295 | // the MaxExponent or MinExponent range. nd is the number of digits in d, as 296 | // computed by NumDigits. Callers can pass unknownNumDigits to indicate that 297 | // they have not yet computed this digit count, in which case setExponent will 298 | // do so. res is any Condition previously set for this operation, which can 299 | // cause Underflow to be set if, for example, Inexact is already set. 300 | func (d *Decimal) setExponent(c *Context, nd int64, res Condition, xs ...int64) Condition { 301 | var sum int64 302 | for _, x := range xs { 303 | if x > MaxExponent { 304 | return SystemOverflow | Overflow 305 | } 306 | if x < MinExponent { 307 | return SystemUnderflow | Underflow 308 | } 309 | sum += x 310 | } 311 | r := int32(sum) 312 | 313 | if nd == unknownNumDigits { 314 | nd = d.NumDigits() 315 | } 316 | // adj is the adjusted exponent: exponent + clength - 1 317 | adj := sum + nd - 1 318 | // Make sure it is less than the system limits. 319 | if adj > MaxExponent { 320 | return SystemOverflow | Overflow 321 | } 322 | if adj < MinExponent { 323 | return SystemUnderflow | Underflow 324 | } 325 | v := int32(adj) 326 | 327 | // d is subnormal. 328 | if v < c.MinExponent { 329 | if !d.IsZero() { 330 | res |= Subnormal 331 | } 332 | Etiny := c.MinExponent - (int32(c.Precision) - 1) 333 | // Only need to round if exponent < Etiny. 334 | if r < Etiny { 335 | // We need to take off (r - Etiny) digits. Split up d.Coeff into integer and 336 | // fractional parts and do operations similar Round. We avoid calling Round 337 | // directly because it calls setExponent and modifies the result's exponent 338 | // and coeff in ways that would be wrong here. 339 | var tmp Decimal 340 | tmp.Coeff.Set(&d.Coeff) 341 | tmp.Exponent = r - Etiny 342 | var integ, frac Decimal 343 | tmp.Modf(&integ, &frac) 344 | frac.Abs(&frac) 345 | if !frac.IsZero() { 346 | res |= Inexact 347 | if c.Rounding.ShouldAddOne(&integ.Coeff, integ.Negative, frac.Cmp(decimalHalf)) { 348 | integ.Coeff.Add(&integ.Coeff, bigOne) 349 | } 350 | } 351 | if integ.IsZero() { 352 | res |= Clamped 353 | } 354 | r = Etiny 355 | d.Coeff.Set(&integ.Coeff) 356 | res |= Rounded 357 | } 358 | } else if v > c.MaxExponent { 359 | if d.IsZero() { 360 | res |= Clamped 361 | r = c.MaxExponent 362 | } else { 363 | res |= Overflow | Inexact 364 | d.Form = Infinite 365 | } 366 | } 367 | 368 | if res.Inexact() && res.Subnormal() { 369 | res |= Underflow 370 | } 371 | 372 | d.Exponent = r 373 | return res 374 | } 375 | 376 | // upscale converts a and b to BigInts with the same scaling. It returns 377 | // them with this scaling, along with the scaling. An error can be produced 378 | // if the resulting scale factor is out of range. The tmp argument must be 379 | // provided and can be (but won't always be) one of the return values. 380 | func upscale(a, b *Decimal, tmp *BigInt) (*BigInt, *BigInt, int32, error) { 381 | if a.Exponent == b.Exponent { 382 | return &a.Coeff, &b.Coeff, a.Exponent, nil 383 | } 384 | swapped := false 385 | if a.Exponent < b.Exponent { 386 | swapped = true 387 | b, a = a, b 388 | } 389 | s := int64(a.Exponent) - int64(b.Exponent) 390 | // TODO(mjibson): figure out a better way to upscale numbers with highly 391 | // differing exponents. 392 | if s > MaxExponent { 393 | return nil, nil, 0, errors.New(errExponentOutOfRangeStr) 394 | } 395 | x := tmp 396 | e := tableExp10(s, x) 397 | x.Mul(&a.Coeff, e) 398 | y := &b.Coeff 399 | if swapped { 400 | x, y = y, x 401 | } 402 | return x, y, b.Exponent, nil 403 | } 404 | 405 | // setBig sets b to d's coefficient with negative. 406 | func (d *Decimal) setBig(b *BigInt) *BigInt { 407 | b.Set(&d.Coeff) 408 | if d.Negative { 409 | b.Neg(b) 410 | } 411 | return b 412 | } 413 | 414 | // CmpTotal compares d and x using their abstract representation rather 415 | // than their numerical value. A total ordering is defined for all possible 416 | // abstract representations, as described below. If the first operand is 417 | // lower in the total order than the second operand then the result is -1, 418 | // if the operands have the same abstract representation then the result is 419 | // 0, and if the first operand is higher in the total order than the second 420 | // operand then the result is 1. 421 | // 422 | // Numbers (representations which are not NaNs) are ordered such that a 423 | // larger numerical value is higher in the ordering. If two representations 424 | // have the same numerical value then the exponent is taken into account; 425 | // larger (more positive) exponents are higher in the ordering. 426 | // 427 | // For example, the following values are ordered from lowest to highest. Note 428 | // the difference in ordering between 1.2300 and 1.23. 429 | // 430 | // -NaN 431 | // -NaNSignaling 432 | // -Infinity 433 | // -127 434 | // -1.00 435 | // -1 436 | // -0.000 437 | // -0 438 | // 0 439 | // 1.2300 440 | // 1.23 441 | // 1E+9 442 | // Infinity 443 | // NaNSignaling 444 | // NaN 445 | func (d *Decimal) CmpTotal(x *Decimal) int { 446 | do := d.cmpOrder() 447 | xo := x.cmpOrder() 448 | 449 | if do < xo { 450 | return -1 451 | } 452 | if do > xo { 453 | return 1 454 | } 455 | 456 | switch d.Form { 457 | case Finite: 458 | // d and x have the same sign and form, compare their value. 459 | if c := d.Cmp(x); c != 0 { 460 | return c 461 | } 462 | 463 | lt := -1 464 | gt := 1 465 | if d.Negative { 466 | lt = 1 467 | gt = -1 468 | } 469 | 470 | // Values are equal, compare exponents. 471 | if d.Exponent < x.Exponent { 472 | return lt 473 | } 474 | if d.Exponent > x.Exponent { 475 | return gt 476 | } 477 | return 0 478 | 479 | case Infinite: 480 | return 0 481 | 482 | default: 483 | return d.Coeff.Cmp(&x.Coeff) 484 | } 485 | } 486 | 487 | func (d *Decimal) cmpOrder() int { 488 | v := int(d.Form) + 1 489 | if d.Negative { 490 | v = -v 491 | } 492 | return v 493 | } 494 | 495 | // Cmp compares x and y and sets d to: 496 | // 497 | // -1 if x < y 498 | // 0 if x == y 499 | // +1 if x > y 500 | // 501 | // This comparison respects the normal rules of special values (like NaN), 502 | // and does not compare them. 503 | func (c *Context) Cmp(d, x, y *Decimal) (Condition, error) { 504 | if c.shouldSetAsNaN(x, y) { 505 | return c.setAsNaN(d, x, y) 506 | } 507 | v := x.Cmp(y) 508 | d.SetInt64(int64(v)) 509 | return 0, nil 510 | } 511 | 512 | // Cmp compares d and x and returns: 513 | // 514 | // -1 if d < x 515 | // 0 if d == x 516 | // +1 if d > x 517 | // undefined if d or x are NaN 518 | func (d *Decimal) Cmp(x *Decimal) int { 519 | ds := d.Sign() 520 | xs := x.Sign() 521 | 522 | // First compare signs. 523 | if ds < xs { 524 | return -1 525 | } else if ds > xs { 526 | return 1 527 | } else if ds == 0 && xs == 0 { 528 | return 0 529 | } 530 | 531 | // Use gt and lt here with flipped signs if d is negative. gt and lt then 532 | // allow for simpler comparisons since we can ignore the sign of the decimals 533 | // and only worry about the form and value. 534 | gt := 1 535 | lt := -1 536 | if ds == -1 { 537 | gt = -1 538 | lt = 1 539 | } 540 | 541 | if d.Form == Infinite { 542 | if x.Form == Infinite { 543 | return 0 544 | } 545 | return gt 546 | } else if x.Form == Infinite { 547 | return lt 548 | } 549 | 550 | if d.Exponent == x.Exponent { 551 | cmp := d.Coeff.Cmp(&x.Coeff) 552 | if ds < 0 { 553 | cmp = -cmp 554 | } 555 | return cmp 556 | } 557 | 558 | // Next compare adjusted exponents. 559 | dn := d.NumDigits() + int64(d.Exponent) 560 | xn := x.NumDigits() + int64(x.Exponent) 561 | if dn < xn { 562 | return lt 563 | } else if dn > xn { 564 | return gt 565 | } 566 | 567 | // Now have to use aligned BigInts. This function previously used upscale to 568 | // align in all cases, but that requires an error in the return value. upscale 569 | // does that so that it can fail if it needs to take the Exp of too-large a 570 | // number, which is very slow. The only way for that to happen here is for d 571 | // and x's coefficients to be of hugely differing values. That is practically 572 | // more difficult, so we are assuming the user is already comfortable with 573 | // slowness in those operations. 574 | 575 | var cmp int 576 | if d.Exponent < x.Exponent { 577 | var xScaled, tmpE BigInt 578 | xScaled.Set(&x.Coeff) 579 | xScaled.Mul(&xScaled, tableExp10(int64(x.Exponent)-int64(d.Exponent), &tmpE)) 580 | cmp = d.Coeff.Cmp(&xScaled) 581 | } else { 582 | var dScaled, tmpE BigInt 583 | dScaled.Set(&d.Coeff) 584 | dScaled.Mul(&dScaled, tableExp10(int64(d.Exponent)-int64(x.Exponent), &tmpE)) 585 | cmp = dScaled.Cmp(&x.Coeff) 586 | } 587 | if ds < 0 { 588 | cmp = -cmp 589 | } 590 | return cmp 591 | } 592 | 593 | // Sign returns, if d is Finite: 594 | // 595 | // -1 if d < 0 596 | // 0 if d == 0 or -0 597 | // +1 if d > 0 598 | // 599 | // Otherwise (if d is Infinite or NaN): 600 | // 601 | // -1 if d.Negative == true 602 | // +1 if d.Negative == false 603 | func (d *Decimal) Sign() int { 604 | if d.Form == Finite && d.Coeff.Sign() == 0 { 605 | return 0 606 | } 607 | if d.Negative { 608 | return -1 609 | } 610 | return 1 611 | } 612 | 613 | // IsZero returns true if d == 0 or -0. 614 | func (d *Decimal) IsZero() bool { 615 | return d.Sign() == 0 616 | } 617 | 618 | // Modf sets integ to the integral part of d and frac to the fractional part 619 | // such that d = integ+frac. If d is negative, both integ or frac will be either 620 | // 0 or negative. integ.Exponent will be >= 0; frac.Exponent will be <= 0. 621 | // Either argument can be nil, preventing it from being set. 622 | func (d *Decimal) Modf(integ, frac *Decimal) { 623 | if integ == nil && frac == nil { 624 | return 625 | } 626 | 627 | neg := d.Negative 628 | 629 | // No fractional part. 630 | if d.Exponent > 0 { 631 | if frac != nil { 632 | frac.Negative = neg 633 | frac.Exponent = 0 634 | frac.Coeff.SetInt64(0) 635 | } 636 | if integ != nil { 637 | integ.Set(d) 638 | } 639 | return 640 | } 641 | nd := d.NumDigits() 642 | exp := -int64(d.Exponent) 643 | // d < 0 because exponent is larger than number of digits. 644 | if exp > nd { 645 | if integ != nil { 646 | integ.Negative = neg 647 | integ.Exponent = 0 648 | integ.Coeff.SetInt64(0) 649 | } 650 | if frac != nil { 651 | frac.Set(d) 652 | } 653 | return 654 | } 655 | 656 | var tmpE BigInt 657 | e := tableExp10(exp, &tmpE) 658 | 659 | var icoeff *BigInt 660 | if integ != nil { 661 | icoeff = &integ.Coeff 662 | integ.Exponent = 0 663 | integ.Negative = neg 664 | } else { 665 | // This is the integ == nil branch, and we already checked if both integ and 666 | // frac were nil above, so frac can never be nil in this branch. 667 | icoeff = new(BigInt) 668 | } 669 | 670 | if frac != nil { 671 | icoeff.QuoRem(&d.Coeff, e, &frac.Coeff) 672 | frac.Exponent = d.Exponent 673 | frac.Negative = neg 674 | } else { 675 | // This is the frac == nil, which means integ must not be nil since they both 676 | // can't be due to the check above. 677 | icoeff.Quo(&d.Coeff, e) 678 | } 679 | } 680 | 681 | // Neg sets d to -x and returns d. 682 | func (d *Decimal) Neg(x *Decimal) *Decimal { 683 | d.Set(x) 684 | if d.IsZero() { 685 | d.Negative = false 686 | } else { 687 | d.Negative = !d.Negative 688 | } 689 | return d 690 | } 691 | 692 | // Abs sets d to |x| and returns d. 693 | func (d *Decimal) Abs(x *Decimal) *Decimal { 694 | d.Set(x) 695 | d.Negative = false 696 | return d 697 | } 698 | 699 | // Reduce sets d to x with all trailing zeros removed and returns d and the 700 | // number of zeros removed. 701 | func (d *Decimal) Reduce(x *Decimal) (*Decimal, int) { 702 | if x.Form != Finite { 703 | d.Set(x) 704 | return d, 0 705 | } 706 | var nd int 707 | neg := false 708 | switch x.Sign() { 709 | case 0: 710 | nd = int(d.NumDigits()) 711 | d.SetInt64(0) 712 | return d, nd - 1 713 | case -1: 714 | neg = true 715 | } 716 | d.Set(x) 717 | 718 | // Use a uint64 for the division if possible. 719 | if d.Coeff.IsUint64() { 720 | i := d.Coeff.Uint64() 721 | for i >= 10000 && i%10000 == 0 { 722 | i /= 10000 723 | nd += 4 724 | } 725 | for i%10 == 0 { 726 | i /= 10 727 | nd++ 728 | } 729 | if nd != 0 { 730 | d.Exponent += int32(nd) 731 | d.Coeff.SetUint64(i) 732 | d.Negative = neg 733 | } 734 | return d, nd 735 | } 736 | 737 | // Divide by 10 in a loop. In benchmarks of reduce0.decTest, this is 20% 738 | // faster than converting to a string and trimming the 0s from the end. 739 | var z, r BigInt 740 | d.setBig(&z) 741 | for { 742 | z.QuoRem(&d.Coeff, bigTen, &r) 743 | if r.Sign() == 0 { 744 | d.Coeff.Set(&z) 745 | nd++ 746 | } else { 747 | break 748 | } 749 | } 750 | d.Exponent += int32(nd) 751 | return d, nd 752 | } 753 | 754 | const decimalSize = unsafe.Sizeof(Decimal{}) 755 | 756 | // Size returns the total memory footprint of d in bytes. 757 | func (d *Decimal) Size() uintptr { 758 | return decimalSize - bigIntSize + d.Coeff.Size() 759 | } 760 | 761 | // Value implements the database/sql/driver.Valuer interface. It converts d to a 762 | // string. 763 | func (d Decimal) Value() (driver.Value, error) { 764 | return d.String(), nil 765 | } 766 | 767 | // Scan implements the database/sql.Scanner interface. It supports string, 768 | // []byte, int64, float64. 769 | func (d *Decimal) Scan(src interface{}) error { 770 | switch src := src.(type) { 771 | case []byte: 772 | _, _, err := d.SetString(string(src)) 773 | return err 774 | case string: 775 | _, _, err := d.SetString(src) 776 | return err 777 | case int64: 778 | d.SetInt64(src) 779 | return nil 780 | case float64: 781 | _, err := d.SetFloat64(src) 782 | return err 783 | default: 784 | return fmt.Errorf("could not convert %T to Decimal", src) 785 | } 786 | } 787 | 788 | // UnmarshalText implements the encoding.TextUnmarshaler interface. 789 | func (d *Decimal) UnmarshalText(b []byte) error { 790 | _, _, err := d.SetString(string(b)) 791 | return err 792 | } 793 | 794 | // MarshalText implements the encoding.TextMarshaler interface. 795 | func (d *Decimal) MarshalText() ([]byte, error) { 796 | if d == nil { 797 | return []byte(""), nil 798 | } 799 | return []byte(d.String()), nil 800 | } 801 | 802 | // NullDecimal represents a string that may be null. NullDecimal implements 803 | // the database/sql.Scanner interface so it can be used as a scan destination: 804 | // 805 | // var d NullDecimal 806 | // err := db.QueryRow("SELECT num FROM foo WHERE id=?", id).Scan(&d) 807 | // ... 808 | // if d.Valid { 809 | // // use d.Decimal 810 | // } else { 811 | // // NULL value 812 | // } 813 | type NullDecimal struct { 814 | Decimal Decimal 815 | Valid bool // Valid is true if Decimal is not NULL 816 | } 817 | 818 | // Scan implements the database/sql.Scanner interface. 819 | func (nd *NullDecimal) Scan(value interface{}) error { 820 | if value == nil { 821 | nd.Valid = false 822 | return nil 823 | } 824 | nd.Valid = true 825 | return nd.Decimal.Scan(value) 826 | } 827 | 828 | // Value implements the database/sql/driver.Valuer interface. 829 | func (nd NullDecimal) Value() (driver.Value, error) { 830 | if !nd.Valid { 831 | return nil, nil 832 | } 833 | return nd.Decimal.Value() 834 | } 835 | -------------------------------------------------------------------------------- /decomposer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | import "fmt" 18 | 19 | // decomposer composes or decomposes a decimal value to and from individual parts. 20 | // There are four separate parts: a boolean negative flag, a form byte with three possible states 21 | // (finite=0, infinite=1, NaN=2), a base-2 big-endian integer 22 | // coefficient (also known as a significand) as a []byte, and an int32 exponent. 23 | // These are composed into a final value as "decimal = (neg) (form=finite) coefficient * 10 ^ exponent". 24 | // A zero length coefficient is a zero value. 25 | // If the form is not finite the coefficient and scale should be ignored. 26 | // The negative parameter may be set to true for any form, although implementations are not required 27 | // to respect the negative parameter in the non-finite form. 28 | // 29 | // Implementations may choose to signal a negative zero or negative NaN, but implementations 30 | // that do not support these may also ignore the negative zero or negative NaN without error. 31 | // If an implementation does not support Infinity it may be converted into a NaN without error. 32 | // If a value is set that is larger then what is supported by an implementation is attempted to 33 | // be set, an error must be returned. 34 | // Implementations must return an error if a NaN or Infinity is attempted to be set while neither 35 | // are supported. 36 | type decomposer interface { 37 | // Decompose returns the internal decimal state into parts. If the provided buf 38 | // has sufficient capacity, buf may be returned as the coefficient with the 39 | // value set and length set as appropriate. Note that it does not act like 40 | // Append-like functions and does not fill necessarily from the beginning of the 41 | // buffer. 42 | Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32) 43 | 44 | // Compose sets the internal decimal value from parts. If the value cannot be 45 | // represented then an error should be returned. 46 | // The coefficent should not be modified. Successive calls to compose with 47 | // the same arguments should result in the same decimal value. 48 | Compose(form byte, negative bool, coefficient []byte, exponent int32) error 49 | } 50 | 51 | var _ decomposer = &Decimal{} 52 | 53 | // Decompose returns the internal decimal state into parts. If the provided buf 54 | // has sufficient capacity, buf may be returned as the coefficient with the 55 | // value set and length set as appropriate. Note that it does not act like 56 | // Append-like functions and does not fill necessarily from the beginning of the 57 | // buffer. 58 | func (d *Decimal) Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32) { 59 | switch d.Form { 60 | default: 61 | panic(fmt.Errorf("unknown Form: %v", d.Form)) 62 | case Finite: 63 | // Nothing, continue on. 64 | case Infinite: 65 | negative = d.Negative 66 | form = 1 67 | return 68 | case NaNSignaling, NaN: 69 | negative = d.Negative 70 | form = 2 71 | return 72 | } 73 | // Finite form. 74 | negative = d.Negative 75 | exponent = d.Exponent 76 | 77 | sizeInBytes := (d.Coeff.BitLen() + 8 - 1) / 8 // math.Ceil(d.Coeff.BitLen()/8.0) 78 | if cap(buf) >= sizeInBytes { 79 | // It extends the buffer as the filling of bytes expects an already 80 | // allocated slice. 81 | buf = buf[:sizeInBytes] 82 | 83 | // We can fit the coefficient in the given buffer which prevents an 84 | // allocation. 85 | coefficient = d.Coeff.FillBytes(buf) 86 | } else { 87 | coefficient = d.Coeff.Bytes() 88 | } 89 | return 90 | } 91 | 92 | // Compose sets the internal decimal value from parts. If the value cannot be 93 | // represented then an error should be returned. 94 | func (d *Decimal) Compose(form byte, negative bool, coefficient []byte, exponent int32) error { 95 | switch form { 96 | default: 97 | return fmt.Errorf("unknown form: %v", form) 98 | case 0: 99 | d.Form = Finite 100 | // Set rest of finite form below. 101 | case 1: 102 | d.Form = Infinite 103 | d.Negative = negative 104 | return nil 105 | case 2: 106 | d.Form = NaN 107 | d.Negative = negative 108 | return nil 109 | } 110 | // Finite form. 111 | d.Negative = negative 112 | d.Coeff.SetBytes(coefficient) 113 | d.Exponent = exponent 114 | return nil 115 | } 116 | -------------------------------------------------------------------------------- /decomposer_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | import ( 18 | "bytes" 19 | "encoding/hex" 20 | "fmt" 21 | "math" 22 | "strconv" 23 | "testing" 24 | ) 25 | 26 | func TestDecomposerRoundTrip(t *testing.T) { 27 | list := []struct { 28 | N string // Name. 29 | S string // String value. 30 | E bool // Expect an error. 31 | }{ 32 | {N: "Zero", S: "0"}, 33 | {N: "Normal-1", S: "123.456"}, 34 | {N: "Normal-2", S: "-123.456"}, 35 | {N: "NaN-1", S: "NaN"}, 36 | {N: "NaN-2", S: "-NaN"}, 37 | {N: "Infinity-1", S: "Infinity"}, 38 | {N: "Infinity-2", S: "-Infinity"}, 39 | } 40 | for _, item := range list { 41 | t.Run(item.N, func(t *testing.T) { 42 | d, _, err := NewFromString(item.S) 43 | if err != nil { 44 | t.Fatal(err) 45 | } 46 | set, set2 := &Decimal{}, &Decimal{} 47 | f, n, c, e := d.Decompose(nil) 48 | err = set.Compose(f, n, c, e) 49 | if err == nil && item.E { 50 | t.Fatal("expected error, got ") 51 | } 52 | err = set2.Compose(f, n, c, e) 53 | if err == nil && item.E { 54 | t.Fatal("expected error, got ") 55 | } 56 | if set.Cmp(set2) != 0 { 57 | t.Fatalf("composing the same value twice resulted in different values. set=%v set2=%v", set, set2) 58 | } 59 | if err != nil && !item.E { 60 | t.Fatalf("unexpected error: %v", err) 61 | } 62 | if set.Cmp(d) != 0 { 63 | t.Fatalf("values incorrect, got %v want %v (%s)", set, d, item.S) 64 | } 65 | }) 66 | } 67 | } 68 | 69 | func TestDecomposerCompose(t *testing.T) { 70 | list := []struct { 71 | N string // Name. 72 | S string // String value. 73 | 74 | Form byte // Form 75 | Neg bool 76 | Coef []byte // Coefficent 77 | Exp int32 78 | 79 | Err bool // Expect an error. 80 | }{ 81 | {N: "Zero", S: "0", Coef: nil, Exp: 0}, 82 | {N: "Normal-1", S: "123.456", Coef: []byte{0x01, 0xE2, 0x40}, Exp: -3}, 83 | {N: "Neg-1", S: "-123.456", Neg: true, Coef: []byte{0x01, 0xE2, 0x40}, Exp: -3}, 84 | {N: "PosExp-1", S: "123456000", Coef: []byte{0x01, 0xE2, 0x40}, Exp: 3}, 85 | {N: "PosExp-2", S: "-123456000", Neg: true, Coef: []byte{0x01, 0xE2, 0x40}, Exp: 3}, 86 | {N: "AllDec-1", S: "0.123456", Coef: []byte{0x01, 0xE2, 0x40}, Exp: -6}, 87 | {N: "AllDec-2", S: "-0.123456", Neg: true, Coef: []byte{0x01, 0xE2, 0x40}, Exp: -6}, 88 | {N: "NaN-1", S: "NaN", Form: 2}, 89 | {N: "NaN-2", S: "-NaN", Form: 2, Neg: true}, 90 | {N: "Infinity-1", S: "Infinity", Form: 1}, 91 | {N: "Infinity-2", S: "-Infinity", Form: 1, Neg: true}, 92 | } 93 | 94 | for _, item := range list { 95 | t.Run(item.N, func(t *testing.T) { 96 | d, _, err := NewFromString(item.S) 97 | if err != nil { 98 | t.Fatal(err) 99 | } 100 | err = d.Compose(item.Form, item.Neg, item.Coef, item.Exp) 101 | if err != nil && !item.Err { 102 | t.Fatalf("unexpected error, got %v", err) 103 | } 104 | if item.Err { 105 | if err == nil { 106 | t.Fatal("expected error, got ") 107 | } 108 | return 109 | } 110 | if s := fmt.Sprintf("%f", d); s != item.S { 111 | t.Fatalf("unexpected value, got %q want %q", s, item.S) 112 | } 113 | }) 114 | } 115 | } 116 | 117 | func TestDecomposerDecompose_usesTheBufferForCoefficientWithSameSize(t *testing.T) { 118 | tests := []struct { 119 | value string 120 | }{ 121 | {"0"}, 122 | {"1"}, 123 | {strconv.FormatUint(math.MaxUint32, 10)}, 124 | {strconv.FormatUint(math.MaxUint64, 10)}, 125 | {"18446744073709551616"}, // math.MaxUint64 + 1 126 | {"36893488147419103230"}, // math.MaxUint64 * 2 127 | } 128 | 129 | for _, test := range tests { 130 | t.Run(test.value, func(t *testing.T) { 131 | value, _, err := NewFromString(test.value) 132 | if err != nil { 133 | t.Fatal("unexpected error", err) 134 | } 135 | 136 | buffer := make([]byte, 0, (value.Coeff.BitLen()+8-1)/8) 137 | 138 | _, _, coef, _ := value.Decompose(buffer) 139 | if !bytes.Equal(coef, value.Coeff.Bytes()) { 140 | t.Fatalf("unexpected different coefficients: %s != %s", hex.EncodeToString(coef), hex.EncodeToString(value.Coeff.Bytes())) 141 | } 142 | 143 | var res BigInt 144 | res.SetBytes(coef) 145 | if res != value.Coeff { 146 | t.Fatal("unexpected different results") 147 | } 148 | }) 149 | } 150 | } 151 | 152 | func TestDecomposerDecompose_usesTheBufferForCoefficientWithBiggerSize(t *testing.T) { 153 | tests := []struct { 154 | value string 155 | }{ 156 | {"0"}, 157 | {"1"}, 158 | {strconv.FormatUint(math.MaxUint32, 10)}, 159 | {strconv.FormatUint(math.MaxUint64, 10)}, 160 | {"18446744073709551616"}, // math.MaxUint64 + 1 161 | {"36893488147419103230"}, // math.MaxUint64 * 2 162 | } 163 | 164 | for _, test := range tests { 165 | t.Run(test.value, func(t *testing.T) { 166 | value, _, err := NewFromString(test.value) 167 | if err != nil { 168 | t.Fatal("unexpected error", err) 169 | } 170 | 171 | buffer := make([]byte, 0, 64) 172 | 173 | _, _, coef, _ := value.Decompose(buffer) 174 | if !bytes.Equal(coef, value.Coeff.Bytes()) { 175 | t.Fatalf("unexpected different coefficients: %s != %s", hex.EncodeToString(coef), hex.EncodeToString(value.Coeff.Bytes())) 176 | } 177 | 178 | var res BigInt 179 | res.SetBytes(coef) 180 | if res != value.Coeff { 181 | t.Fatal("unexpected different results") 182 | } 183 | }) 184 | } 185 | } 186 | 187 | func TestDecomposerDecompose_ignoresBufferIfItDoesNotFit(t *testing.T) { 188 | value := New(42, 0) 189 | buffer := make([]byte, 0) 190 | 191 | _, _, coef, _ := value.Decompose(buffer) 192 | if !bytes.Equal([]byte{42}, coef) { 193 | t.Fatal("unexpected different buffers", coef) 194 | } 195 | 196 | _, _, coef, _ = value.Decompose(nil) 197 | if !bytes.Equal([]byte{42}, coef) { 198 | t.Fatal("unexpected different buffers with ", coef) 199 | } 200 | } 201 | 202 | func TestDecomposerDecompose_usesBufferWithNonZeroLength(t *testing.T) { 203 | value := New(42, 0) 204 | buffer := make([]byte, 4) 205 | 206 | _, _, coef, _ := value.Decompose(buffer) 207 | if !bytes.Equal([]byte{42}, coef) { 208 | t.Fatal("unexpected different buffers", coef) 209 | } 210 | } 211 | 212 | func TestDecomposerDecompose_usesBufferWithNonZeroCapacity(t *testing.T) { 213 | value := New(42, 0) 214 | buffer := make([]byte, 0, 4) 215 | 216 | _, _, coef, _ := value.Decompose(buffer) 217 | if !bytes.Equal([]byte{42}, coef) { 218 | t.Fatal("unexpected different buffers", coef) 219 | } 220 | } 221 | 222 | func TestDecomposerDecompose_extendsBufferWithNonZeroLength(t *testing.T) { 223 | value := New(math.MaxInt64, 0) 224 | buffer := make([]byte, 2) 225 | 226 | _, _, coef, _ := value.Decompose(buffer) 227 | if !bytes.Equal([]byte{127, 255, 255, 255, 255, 255, 255, 255}, coef) { 228 | t.Fatal("unexpected different buffers", coef) 229 | } 230 | } 231 | 232 | func BenchmarkDecomposerDecompose(b *testing.B) { 233 | b.Run("no allocation", func(b *testing.B) { 234 | buf := make([]byte, 0, 8) 235 | value := New(42, -1) 236 | 237 | for i := 0; i < b.N; i++ { 238 | _, _, _, _ = value.Decompose(buf) 239 | } 240 | }) 241 | b.Run("one allocation", func(b *testing.B) { 242 | value := New(42, -1) 243 | 244 | for i := 0; i < b.N; i++ { 245 | _, _, _, _ = value.Decompose(nil) 246 | } 247 | }) 248 | } 249 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | /* 16 | Package apd implements arbitrary-precision decimals. 17 | 18 | apd implements much of the decimal specification from the General 19 | Decimal Arithmetic (http://speleotrove.com/decimal/) description, which 20 | is refered to here as GDA. This is the same specification implemented by 21 | pythons decimal module (https://docs.python.org/2/library/decimal.html) 22 | and GCCs decimal extension. 23 | 24 | Features 25 | 26 | Panic-free operation. The math/big types don’t return errors, and instead 27 | panic under some conditions that are documented. This requires users to 28 | validate the inputs before using them. Meanwhile, we’d like our decimal 29 | operations to have more failure modes and more input requirements than the 30 | math/big types, so using that API would be difficult. apd instead returns 31 | errors when needed. 32 | 33 | Support for standard functions. sqrt, ln, pow, etc. 34 | 35 | Accurate and configurable precision. Operations will use enough internal 36 | precision to produce a correct result at the requested precision. Precision 37 | is set by a "context" structure that accompanies the function arguments, 38 | as discussed in the next section. 39 | 40 | Good performance. Operations will either be fast enough or will produce an 41 | error if they will be slow. This prevents edge-case operations from consuming 42 | lots of CPU or memory. 43 | 44 | Condition flags and traps. All operations will report whether their 45 | result is exact, is rounded, is over- or under-flowed, is subnormal 46 | (https://en.wikipedia.org/wiki/Denormal_number), or is some other 47 | condition. apd supports traps which will trigger an error on any of these 48 | conditions. This makes it possible to guarantee exactness in computations, 49 | if needed. 50 | 51 | SQL scan and value methods are implemented. This allows the use of Decimals as 52 | placeholder parameters and row result Scan destinations. 53 | 54 | Usage 55 | 56 | apd has two main types. The first is Decimal which holds the values of 57 | decimals. It is simple and uses a big.Int with an exponent to describe 58 | values. Most operations on Decimals can’t produce errors as they work 59 | directly on the underlying big.Int. Notably, however, there are no arithmetic 60 | operations on Decimals. 61 | 62 | The second main type is Context, which is where all arithmetic operations 63 | are defined. A Context describes the precision, range, and some other 64 | restrictions during operations. These operations can all produce failures, 65 | and so return errors. 66 | 67 | Context operations, in addition to errors, return a Condition, which is a 68 | bitfield of flags that occurred during an operation. These include overflow, 69 | underflow, inexact, rounded, and others. The Traps field of a Context can be 70 | set which will produce an error if the corresponding flag occurs. An example 71 | of this is given below. 72 | 73 | */ 74 | package apd 75 | -------------------------------------------------------------------------------- /error.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | // MakeErrDecimal creates a ErrDecimal with given context. 18 | func MakeErrDecimal(c *Context) ErrDecimal { 19 | return ErrDecimal{ 20 | Ctx: c, 21 | } 22 | } 23 | 24 | // ErrDecimal performs operations on decimals and collects errors during 25 | // operations. If an error is already set, the operation is skipped. Designed to 26 | // be used for many operations in a row, with a single error check at the end. 27 | type ErrDecimal struct { 28 | err error 29 | Ctx *Context 30 | // Flags are the accumulated flags from operations. 31 | Flags Condition 32 | } 33 | 34 | // Err returns the first error encountered or the context's trap error 35 | // if present. 36 | func (e *ErrDecimal) Err() error { 37 | if e.err != nil { 38 | return e.err 39 | } 40 | if e.Ctx != nil { 41 | _, e.err = e.Ctx.goError(e.Flags) 42 | return e.err 43 | } 44 | return nil 45 | } 46 | 47 | // update adjusts the ErrDecimal's state with the result of an operation. 48 | func (e *ErrDecimal) update(res Condition, err error) { 49 | e.Flags |= res 50 | e.err = err 51 | } 52 | 53 | // Abs performs e.Ctx.Abs(d, x) and returns d. 54 | func (e *ErrDecimal) Abs(d, x *Decimal) *Decimal { 55 | if e.Err() != nil { 56 | return d 57 | } 58 | e.update(e.Ctx.Abs(d, x)) 59 | return d 60 | } 61 | 62 | // Add performs e.Ctx.Add(d, x, y) and returns d. 63 | func (e *ErrDecimal) Add(d, x, y *Decimal) *Decimal { 64 | if e.Err() != nil { 65 | return d 66 | } 67 | e.update(e.Ctx.Add(d, x, y)) 68 | return d 69 | } 70 | 71 | // Ceil performs e.Ctx.Ceil(d, x) and returns d. 72 | func (e *ErrDecimal) Ceil(d, x *Decimal) *Decimal { 73 | if e.Err() != nil { 74 | return d 75 | } 76 | e.update(e.Ctx.Ceil(d, x)) 77 | return d 78 | } 79 | 80 | // Exp performs e.Ctx.Exp(d, x) and returns d. 81 | func (e *ErrDecimal) Exp(d, x *Decimal) *Decimal { 82 | if e.Err() != nil { 83 | return d 84 | } 85 | e.update(e.Ctx.Exp(d, x)) 86 | return d 87 | } 88 | 89 | // Floor performs e.Ctx.Floor(d, x) and returns d. 90 | func (e *ErrDecimal) Floor(d, x *Decimal) *Decimal { 91 | if e.Err() != nil { 92 | return d 93 | } 94 | e.update(e.Ctx.Floor(d, x)) 95 | return d 96 | } 97 | 98 | // Int64 returns 0 if err is set. Otherwise returns d.Int64(). 99 | func (e *ErrDecimal) Int64(d *Decimal) int64 { 100 | if e.Err() != nil { 101 | return 0 102 | } 103 | var r int64 104 | r, e.err = d.Int64() 105 | return r 106 | } 107 | 108 | // Ln performs e.Ctx.Ln(d, x) and returns d. 109 | func (e *ErrDecimal) Ln(d, x *Decimal) *Decimal { 110 | if e.Err() != nil { 111 | return d 112 | } 113 | e.update(e.Ctx.Ln(d, x)) 114 | return d 115 | } 116 | 117 | // Log10 performs d.Log10(x) and returns d. 118 | func (e *ErrDecimal) Log10(d, x *Decimal) *Decimal { 119 | if e.Err() != nil { 120 | return d 121 | } 122 | e.update(e.Ctx.Log10(d, x)) 123 | return d 124 | } 125 | 126 | // Mul performs e.Ctx.Mul(d, x, y) and returns d. 127 | func (e *ErrDecimal) Mul(d, x, y *Decimal) *Decimal { 128 | if e.Err() != nil { 129 | return d 130 | } 131 | e.update(e.Ctx.Mul(d, x, y)) 132 | return d 133 | } 134 | 135 | // Neg performs e.Ctx.Neg(d, x) and returns d. 136 | func (e *ErrDecimal) Neg(d, x *Decimal) *Decimal { 137 | if e.Err() != nil { 138 | return d 139 | } 140 | e.update(e.Ctx.Neg(d, x)) 141 | return d 142 | } 143 | 144 | // Pow performs e.Ctx.Pow(d, x, y) and returns d. 145 | func (e *ErrDecimal) Pow(d, x, y *Decimal) *Decimal { 146 | if e.Err() != nil { 147 | return d 148 | } 149 | e.update(e.Ctx.Pow(d, x, y)) 150 | return d 151 | } 152 | 153 | // Quantize performs e.Ctx.Quantize(d, v, exp) and returns d. 154 | func (e *ErrDecimal) Quantize(d, v *Decimal, exp int32) *Decimal { 155 | if e.Err() != nil { 156 | return d 157 | } 158 | e.update(e.Ctx.Quantize(d, v, exp)) 159 | return d 160 | } 161 | 162 | // Quo performs e.Ctx.Quo(d, x, y) and returns d. 163 | func (e *ErrDecimal) Quo(d, x, y *Decimal) *Decimal { 164 | if e.Err() != nil { 165 | return d 166 | } 167 | e.update(e.Ctx.Quo(d, x, y)) 168 | return d 169 | } 170 | 171 | // QuoInteger performs e.Ctx.QuoInteger(d, x, y) and returns d. 172 | func (e *ErrDecimal) QuoInteger(d, x, y *Decimal) *Decimal { 173 | if e.Err() != nil { 174 | return d 175 | } 176 | e.update(e.Ctx.QuoInteger(d, x, y)) 177 | return d 178 | } 179 | 180 | // Reduce performs e.Ctx.Reduce(d, x) and returns the number of zeros removed 181 | // and d. 182 | func (e *ErrDecimal) Reduce(d, x *Decimal) (int, *Decimal) { 183 | if e.Err() != nil { 184 | return 0, d 185 | } 186 | n, res, err := e.Ctx.Reduce(d, x) 187 | e.update(res, err) 188 | return n, d 189 | } 190 | 191 | // Rem performs e.Ctx.Rem(d, x, y) and returns d. 192 | func (e *ErrDecimal) Rem(d, x, y *Decimal) *Decimal { 193 | if e.Err() != nil { 194 | return d 195 | } 196 | e.update(e.Ctx.Rem(d, x, y)) 197 | return d 198 | } 199 | 200 | // Round performs e.Ctx.Round(d, x) and returns d. 201 | func (e *ErrDecimal) Round(d, x *Decimal) *Decimal { 202 | if e.Err() != nil { 203 | return d 204 | } 205 | e.update(e.Ctx.Round(d, x)) 206 | return d 207 | } 208 | 209 | // Sqrt performs e.Ctx.Sqrt(d, x) and returns d. 210 | func (e *ErrDecimal) Sqrt(d, x *Decimal) *Decimal { 211 | if e.Err() != nil { 212 | return d 213 | } 214 | e.update(e.Ctx.Sqrt(d, x)) 215 | return d 216 | } 217 | 218 | // Sub performs e.Ctx.Sub(d, x, y) and returns d. 219 | func (e *ErrDecimal) Sub(d, x, y *Decimal) *Decimal { 220 | if e.Err() != nil { 221 | return d 222 | } 223 | e.update(e.Ctx.Sub(d, x, y)) 224 | return d 225 | } 226 | 227 | // RoundToIntegralValue performs e.Ctx.RoundToIntegralValue(d, x) and returns d. 228 | func (e *ErrDecimal) RoundToIntegralValue(d, x *Decimal) *Decimal { 229 | if e.Err() != nil { 230 | return d 231 | } 232 | e.update(e.Ctx.RoundToIntegralValue(d, x)) 233 | return d 234 | } 235 | 236 | // RoundToIntegralExact performs e.Ctx.RoundToIntegralExact(d, x) and returns d. 237 | func (e *ErrDecimal) RoundToIntegralExact(d, x *Decimal) *Decimal { 238 | if e.Err() != nil { 239 | return d 240 | } 241 | e.update(e.Ctx.RoundToIntegralExact(d, x)) 242 | return d 243 | } 244 | -------------------------------------------------------------------------------- /error_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | import "testing" 18 | 19 | // Appease the unused test. 20 | // TODO(mjibson): actually test all the ErrDecimal methods. 21 | func TestErrDecimal(t *testing.T) { 22 | ed := MakeErrDecimal(testCtx) 23 | a := New(1, 0) 24 | ed.Abs(a, a) 25 | ed.Exp(a, a) 26 | ed.Ln(a, a) 27 | ed.Log10(a, a) 28 | ed.Neg(a, a) 29 | ed.Pow(a, a, a) 30 | ed.QuoInteger(a, a, a) 31 | ed.Rem(a, a, a) 32 | ed.Round(a, a) 33 | } 34 | 35 | // TestMakeErrDecimalWithPrecision tests that WithPrecision generates a copy 36 | // and not a reference. 37 | func TestMakeErrDecimalWithPrecision(t *testing.T) { 38 | c := &Context{ 39 | Precision: 5, 40 | MaxExponent: 2, 41 | } 42 | nc := c.WithPrecision(c.Precision * 2) 43 | ed := MakeErrDecimal(nc) 44 | if ed.Ctx.Precision != 10 { 45 | t.Fatalf("expected %d, got %d", 10, ed.Ctx.Precision) 46 | } 47 | if c.Precision != 5 { 48 | t.Fatalf("expected %d, got %d", 5, c.Precision) 49 | } 50 | if c.MaxExponent != 2 { 51 | t.Fatalf("expected %d, got %d", 2, c.MaxExponent) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd_test 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/cockroachdb/apd/v3" 21 | ) 22 | 23 | // ExampleOverflow demonstrates how to detect or error on overflow. 24 | func ExampleContext_overflow() { 25 | // Create a context that will overflow at 1e3. 26 | c := apd.Context{ 27 | MaxExponent: 2, 28 | Traps: apd.Overflow, 29 | } 30 | one := apd.New(1, 0) 31 | d := apd.New(997, 0) 32 | for { 33 | res, err := c.Add(d, d, one) 34 | fmt.Printf("d: %8s, overflow: %5v, err: %v\n", d, res.Overflow(), err) 35 | if err != nil { 36 | return 37 | } 38 | } 39 | // Output: 40 | // d: 998, overflow: false, err: 41 | // d: 999, overflow: false, err: 42 | // d: Infinity, overflow: true, err: overflow 43 | } 44 | 45 | // ExampleInexact demonstrates how to detect inexact operations. 46 | func ExampleContext_inexact() { 47 | d := apd.New(27, 0) 48 | three := apd.New(3, 0) 49 | c := apd.BaseContext.WithPrecision(5) 50 | for { 51 | res, err := c.Quo(d, d, three) 52 | fmt.Printf("d: %7s, inexact: %5v, err: %v\n", d, res.Inexact(), err) 53 | if err != nil { 54 | return 55 | } 56 | if res.Inexact() { 57 | return 58 | } 59 | } 60 | // Output: 61 | // d: 9.0000, inexact: false, err: 62 | // d: 3.0000, inexact: false, err: 63 | // d: 1.0000, inexact: false, err: 64 | // d: 0.33333, inexact: true, err: 65 | } 66 | 67 | func ExampleContext_Quantize() { 68 | input, _, _ := apd.NewFromString("123.45") 69 | output := new(apd.Decimal) 70 | c := apd.BaseContext.WithPrecision(10) 71 | for i := int32(-3); i <= 3; i++ { 72 | res, _ := c.Quantize(output, input, i) 73 | fmt.Printf("%2v: %s", i, output) 74 | if res != 0 { 75 | fmt.Printf(" (%s)", res) 76 | } 77 | fmt.Println() 78 | } 79 | // Output: 80 | // -3: 123.450 81 | // -2: 123.45 82 | // -1: 123.5 (inexact, rounded) 83 | // 0: 123 (inexact, rounded) 84 | // 1: 1.2E+2 (inexact, rounded) 85 | // 2: 1E+2 (inexact, rounded) 86 | // 3: 0E+3 (inexact, rounded) 87 | } 88 | 89 | func ExampleErrDecimal() { 90 | c := apd.BaseContext.WithPrecision(5) 91 | ed := apd.MakeErrDecimal(c) 92 | d := apd.New(10, 0) 93 | fmt.Printf("%s, err: %v\n", d, ed.Err()) 94 | ed.Add(d, d, apd.New(2, 1)) // add 20 95 | fmt.Printf("%s, err: %v\n", d, ed.Err()) 96 | ed.Quo(d, d, apd.New(0, 0)) // divide by zero 97 | fmt.Printf("%s, err: %v\n", d, ed.Err()) 98 | ed.Sub(d, d, apd.New(1, 0)) // attempt to subtract 1 99 | // The subtraction doesn't occur and doesn't change the error. 100 | fmt.Printf("%s, err: %v\n", d, ed.Err()) 101 | // Output: 102 | // 10, err: 103 | // 30, err: 104 | // Infinity, err: division by zero 105 | // Infinity, err: division by zero 106 | } 107 | 108 | // ExampleRoundToIntegralExact demonstrates how to use RoundToIntegralExact to 109 | // check if a number is an integer or not. Note the variations between integer 110 | // (which allows zeros after the decimal point) and strict (which does not). See 111 | // the documentation on Inexact and Rounded. 112 | func ExampleContext_RoundToIntegralExact() { 113 | inputs := []string{ 114 | "123.4", 115 | "123.0", 116 | "123", 117 | "12E1", 118 | "120E-1", 119 | "120E-2", 120 | } 121 | for _, input := range inputs { 122 | d, _, _ := apd.NewFromString(input) 123 | res, _ := apd.BaseContext.RoundToIntegralExact(d, d) 124 | integer := !res.Inexact() 125 | strict := !res.Rounded() 126 | fmt.Printf("input: % 6s, output: %3s, integer: %5t, strict: %5t, res:", input, d, integer, strict) 127 | if res != 0 { 128 | fmt.Printf(" %s", res) 129 | } 130 | fmt.Println() 131 | } 132 | // Output: 133 | // input: 123.4, output: 123, integer: false, strict: false, res: inexact, rounded 134 | // input: 123.0, output: 123, integer: true, strict: false, res: rounded 135 | // input: 123, output: 123, integer: true, strict: true, res: 136 | // input: 12E1, output: 120, integer: true, strict: true, res: 137 | // input: 120E-1, output: 12, integer: true, strict: false, res: rounded 138 | // input: 120E-2, output: 1, integer: false, strict: false, res: inexact, rounded 139 | } 140 | -------------------------------------------------------------------------------- /form_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=Form"; DO NOT EDIT. 2 | 3 | package apd 4 | 5 | import "fmt" 6 | 7 | const _Form_name = "FiniteInfiniteNaNSignalingNaN" 8 | 9 | var _Form_index = [...]uint8{0, 6, 14, 26, 29} 10 | 11 | func (i Form) String() string { 12 | if i < 0 || i >= Form(len(_Form_index)-1) { 13 | return fmt.Sprintf("Form(%d)", i) 14 | } 15 | return _Form_name[_Form_index[i]:_Form_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /format.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Adapted from math/big/ftoa.go. 6 | 7 | package apd 8 | 9 | import ( 10 | "fmt" 11 | "strconv" 12 | ) 13 | 14 | // Text converts the floating-point number x to a string according 15 | // to the given format. The format is one of: 16 | // 17 | // 'e' -d.dddde±dd, decimal exponent, exponent digits 18 | // 'E' -d.ddddE±dd, decimal exponent, exponent digits 19 | // 'f' -ddddd.dddd, no exponent 20 | // 'g' like 'e' for large exponents, like 'f' otherwise 21 | // 'G' like 'E' for large exponents, like 'f' otherwise 22 | // 23 | // If format is a different character, Text returns a "%" followed by the 24 | // unrecognized.Format character. The 'f' format has the possibility of 25 | // displaying precision that is not present in the Decimal when it appends 26 | // zeros (the 'g' format avoids the use of 'f' in this case). All other 27 | // formats always show the exact precision of the Decimal. 28 | func (d *Decimal) Text(format byte) string { 29 | var buf [16]byte 30 | return string(d.Append(buf[:0], format)) 31 | } 32 | 33 | // String formats x like x.Text('G'). It matches the to-scientific-string 34 | // conversion of the GDA spec. 35 | func (d *Decimal) String() string { 36 | return d.Text('G') 37 | } 38 | 39 | // lowestZeroNegativeCoefficientCockroach is the smallest co-efficient in 40 | // Cockroach supports using 0E. 41 | const lowestZeroNegativeCoefficientCockroach = -2000 42 | 43 | // Append appends to buf the string form of the decimal number d, 44 | // as generated by d.Text, and returns the extended buffer. 45 | func (d *Decimal) Append(buf []byte, fmtString byte) []byte { 46 | // sign 47 | if d.Negative { 48 | buf = append(buf, '-') 49 | } 50 | 51 | switch d.Form { 52 | case Finite: 53 | // ignore 54 | case NaN: 55 | return append(buf, "NaN"...) 56 | case NaNSignaling: 57 | return append(buf, "sNaN"...) 58 | case Infinite: 59 | return append(buf, "Infinity"...) 60 | default: 61 | return append(buf, "unknown"...) 62 | } 63 | 64 | var scratch [16]byte 65 | digits := d.Coeff.Append(scratch[:0], 10) 66 | switch fmtString { 67 | case 'e', 'E': 68 | return fmtE(buf, fmtString, d, digits) 69 | case 'f': 70 | return fmtF(buf, d, digits) 71 | case 'g', 'G': 72 | digitLen := len(digits) 73 | // PG formats all 0s after the decimal point in the 0E- case 74 | // (e.g. 0E-9 should be 0.000000000). With the `adjExponentLimit` below, 75 | // this does not do that, so for 0 with negative coefficients we pad 76 | // the digit length. 77 | // Ref: https://github.com/cockroachdb/cockroach/issues/102217 78 | // 79 | // To avoid leaking too much memory for pathological cases, e.g. 80 | // 0E-100000000, we also fall back to the default exponent format 81 | // handling when the exponent is below cockroach's lowest supported 0 82 | // coefficient. 83 | if d.Coeff.BitLen() == 0 && d.Exponent >= lowestZeroNegativeCoefficientCockroach && d.Exponent < 0 { 84 | digitLen += int(-d.Exponent) 85 | } 86 | // See: http://speleotrove.com/decimal/daconvs.html#reftostr 87 | const adjExponentLimit = -6 88 | adj := int(d.Exponent) + (digitLen - 1) 89 | if d.Exponent <= 0 && adj >= adjExponentLimit { 90 | return fmtF(buf, d, digits) 91 | } 92 | // We need to convert the either g or G into a e or E since that's what fmtE 93 | // expects. This is indeed fmtString - 2, but attempting to do that in a way that 94 | // illustrates the intention. 95 | return fmtE(buf, fmtString+'e'-'g', d, digits) 96 | } 97 | 98 | if d.Negative { 99 | buf = buf[:len(buf)-1] // sign was added prematurely - remove it again 100 | } 101 | return append(buf, '%', fmtString) 102 | } 103 | 104 | // %e: d.ddddde±d 105 | func fmtE(buf []byte, fmt byte, d *Decimal, digits []byte) []byte { 106 | adj := int64(d.Exponent) + int64(len(digits)) - 1 107 | buf = append(buf, digits[0]) 108 | if len(digits) > 1 { 109 | buf = append(buf, '.') 110 | buf = append(buf, digits[1:]...) 111 | } 112 | buf = append(buf, fmt) 113 | var ch byte 114 | if adj < 0 { 115 | ch = '-' 116 | adj = -adj 117 | } else { 118 | ch = '+' 119 | } 120 | buf = append(buf, ch) 121 | return strconv.AppendInt(buf, adj, 10) 122 | } 123 | 124 | // %f: ddddddd.ddddd 125 | func fmtF(buf []byte, d *Decimal, digits []byte) []byte { 126 | if d.Exponent < 0 { 127 | if left := -int(d.Exponent) - len(digits); left >= 0 { 128 | buf = append(buf, "0."...) 129 | for i := 0; i < left; i++ { 130 | buf = append(buf, '0') 131 | } 132 | buf = append(buf, digits...) 133 | } else if left < 0 { 134 | offset := -left 135 | buf = append(buf, digits[:offset]...) 136 | buf = append(buf, '.') 137 | buf = append(buf, digits[offset:]...) 138 | } 139 | } else if d.Exponent >= 0 { 140 | buf = append(buf, digits...) 141 | for i := int32(0); i < d.Exponent; i++ { 142 | buf = append(buf, '0') 143 | } 144 | } 145 | return buf 146 | } 147 | 148 | var _ fmt.Formatter = decimalZero // *Decimal must implement fmt.Formatter 149 | 150 | // Format implements fmt.Formatter. It accepts many of the regular formats for 151 | // floating-point numbers ('e', 'E', 'f', 'F', 'g', 'G') as well as 's' and 'v', 152 | // which are handled like 'G'. Format also supports the output field width, as 153 | // well as the format flags '+' and ' ' for sign control, '0' for space or zero 154 | // padding, and '-' for left or right justification. It does not support 155 | // precision. See the fmt package for details. 156 | func (d *Decimal) Format(s fmt.State, format rune) { 157 | switch format { 158 | case 'e', 'E', 'f', 'g', 'G': 159 | // nothing to do 160 | case 'F': 161 | // (*Decimal).Text doesn't support 'F'; handle like 'f' 162 | format = 'f' 163 | case 'v', 's': 164 | // handle like 'G' 165 | format = 'G' 166 | default: 167 | fmt.Fprintf(s, "%%!%c(*apd.Decimal=%s)", format, d.String()) 168 | return 169 | } 170 | var buf []byte 171 | buf = d.Append(buf, byte(format)) 172 | if len(buf) == 0 { 173 | buf = []byte("?") // should never happen, but don't crash 174 | } 175 | // len(buf) > 0 176 | 177 | var sign string 178 | switch { 179 | case buf[0] == '-': 180 | sign = "-" 181 | buf = buf[1:] 182 | case buf[0] == '+': 183 | // +Inf 184 | sign = "+" 185 | if s.Flag(' ') { 186 | sign = " " 187 | } 188 | buf = buf[1:] 189 | case s.Flag('+'): 190 | sign = "+" 191 | case s.Flag(' '): 192 | sign = " " 193 | } 194 | 195 | var padding int 196 | if width, hasWidth := s.Width(); hasWidth && width > len(sign)+len(buf) { 197 | padding = width - len(sign) - len(buf) 198 | } 199 | 200 | switch { 201 | case s.Flag('0') && d.Form == Finite: 202 | // 0-padding on left 203 | writeMultiple(s, sign, 1) 204 | writeMultiple(s, "0", padding) 205 | s.Write(buf) 206 | case s.Flag('-'): 207 | // padding on right 208 | writeMultiple(s, sign, 1) 209 | s.Write(buf) 210 | writeMultiple(s, " ", padding) 211 | default: 212 | // padding on left 213 | writeMultiple(s, " ", padding) 214 | writeMultiple(s, sign, 1) 215 | s.Write(buf) 216 | } 217 | } 218 | 219 | // write count copies of text to s 220 | func writeMultiple(s fmt.State, text string, count int) { 221 | if len(text) > 0 { 222 | b := []byte(text) 223 | for ; count > 0; count-- { 224 | s.Write(b) 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/cockroachdb/apd/v3 2 | 3 | go 1.17 4 | 5 | require github.com/lib/pq v1.10.7 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= 2 | github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 3 | -------------------------------------------------------------------------------- /loop.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This file is adapted from https://github.com/robpike/ivy/blob/master/value/loop.go. 6 | 7 | package apd 8 | 9 | import ( 10 | "fmt" 11 | "math" 12 | ) 13 | 14 | type loop struct { 15 | c *Context 16 | name string // The name of the function we are evaluating. 17 | i uint64 // Loop count. 18 | precision int32 19 | maxIterations uint64 // When to give up. 20 | arg *Decimal // original argument to function; only used for diagnostic. 21 | prevZ Decimal // Result from the previous iteration. 22 | delta Decimal // |Change| from previous iteration. 23 | } 24 | 25 | const digitsToBitsRatio = math.Ln10 / math.Ln2 26 | 27 | // newLoop returns a new loop checker. Arguments: 28 | // - name: name of the function being calculated (for error messages) 29 | // - arg: argument to the function (for error messages) 30 | // - precision: desired precision; the loop ends when consecutive estimates 31 | // differ less than the desired precision. Note that typically 32 | // the inner computations in an iteration need higher precision, 33 | // so this is normally lower than the precision in the context. 34 | // - maxItersPerDigit: after this many iterations per digit of precision, the 35 | // loop ends in error. 36 | func (c *Context) newLoop(name string, arg *Decimal, precision uint32, maxItersPerDigit int) *loop { 37 | return &loop{ 38 | c: c, 39 | name: name, 40 | arg: new(Decimal).Set(arg), 41 | precision: int32(precision), 42 | maxIterations: 10 + uint64(maxItersPerDigit*int(precision)), 43 | } 44 | } 45 | 46 | // done reports whether the loop is done. If it does not converge 47 | // after the maximum number of iterations, it returns an error. 48 | func (l *loop) done(z *Decimal) (bool, error) { 49 | if _, err := l.c.Sub(&l.delta, &l.prevZ, z); err != nil { 50 | return false, err 51 | } 52 | sign := l.delta.Sign() 53 | if sign == 0 { 54 | return true, nil 55 | } 56 | if sign < 0 { 57 | // Convergence can oscillate when the calculation is nearly 58 | // done and we're running out of bits. This stops that. 59 | // See next comment. 60 | l.delta.Neg(&l.delta) 61 | } 62 | 63 | // We stop if the delta is smaller than a change of 1 in the 64 | // (l.precision)-th digit of z. Examples: 65 | // 66 | // p = 4 67 | // z = 12345.678 = 12345678 * 10^-3 68 | // eps = 10.000 = 10^(-4+8-3) 69 | // 70 | // p = 3 71 | // z = 0.001234 = 1234 * 10^-6 72 | // eps = 0.00001 = 10^(-3+4-6) 73 | var eps Decimal 74 | eps.Coeff.Set(bigOne) 75 | eps.Exponent = -l.precision + int32(z.NumDigits()) + z.Exponent 76 | if l.delta.Cmp(&eps) <= 0 { 77 | return true, nil 78 | } 79 | l.i++ 80 | if l.i == l.maxIterations { 81 | return false, fmt.Errorf( 82 | "%s %s: did not converge after %d iterations; prev,last result %s,%s delta %s precision: %d", 83 | l.name, l.arg.String(), l.maxIterations, z.String(), l.prevZ.String(), l.delta.String(), l.precision, 84 | ) 85 | } 86 | l.prevZ.Set(z) 87 | return false, nil 88 | } 89 | -------------------------------------------------------------------------------- /round.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | // Round sets d to rounded x, rounded to the precision specified by c. If c 18 | // has zero precision, no rounding will occur. If c has no Rounding specified, 19 | // RoundHalfUp is used. 20 | func (c *Context) Round(d, x *Decimal) (Condition, error) { 21 | return c.goError(c.round(d, x)) 22 | } 23 | 24 | //gcassert:inline 25 | func (c *Context) round(d, x *Decimal) Condition { 26 | return c.Rounding.Round(c, d, x, true /* disableIfPrecisionZero */) 27 | } 28 | 29 | // Rounder specifies the behavior of rounding. 30 | type Rounder string 31 | 32 | // ShouldAddOne returns true if 1 should be added to the absolute value 33 | // of a number being rounded. result is the result to which the 1 would 34 | // be added. neg is true if the number is negative. half is -1 if the 35 | // discarded digits are < 0.5, 0 if = 0.5, or 1 if > 0.5. 36 | func (r Rounder) ShouldAddOne(result *BigInt, neg bool, half int) bool { 37 | // NOTE: this is written using a switch statement instead of some 38 | // other form of dynamic dispatch to assist Go's escape analysis. 39 | switch r { 40 | case RoundDown: 41 | return roundDown(result, neg, half) 42 | case RoundHalfUp: 43 | return roundHalfUp(result, neg, half) 44 | case RoundHalfEven: 45 | return roundHalfEven(result, neg, half) 46 | case RoundCeiling: 47 | return roundCeiling(result, neg, half) 48 | case RoundFloor: 49 | return roundFloor(result, neg, half) 50 | case RoundHalfDown: 51 | return roundHalfDown(result, neg, half) 52 | case RoundUp: 53 | return roundUp(result, neg, half) 54 | case Round05Up: 55 | return round05Up(result, neg, half) 56 | default: 57 | return roundHalfUp(result, neg, half) 58 | } 59 | } 60 | 61 | // Round sets d to rounded x. 62 | func (r Rounder) Round(c *Context, d, x *Decimal, disableIfPrecisionZero bool) Condition { 63 | d.Set(x) 64 | nd := x.NumDigits() 65 | xs := x.Sign() 66 | var res Condition 67 | 68 | if disableIfPrecisionZero && c.Precision == 0 { 69 | // Rounding has been disabled. 70 | return d.setExponent(c, nd, res, int64(d.Exponent)) 71 | } 72 | 73 | // adj is the adjusted exponent: exponent + clength - 1 74 | if adj := int64(x.Exponent) + nd - 1; xs != 0 && adj < int64(c.MinExponent) { 75 | // Subnormal is defined before rounding. 76 | res |= Subnormal 77 | // setExponent here to prevent double-rounded subnormals. 78 | res |= d.setExponent(c, nd, res, int64(d.Exponent)) 79 | return res 80 | } 81 | 82 | diff := nd - int64(c.Precision) 83 | if diff > 0 { 84 | if diff > MaxExponent { 85 | return SystemOverflow | Overflow 86 | } 87 | if diff < MinExponent { 88 | return SystemUnderflow | Underflow 89 | } 90 | res |= Rounded 91 | var y, m BigInt 92 | e := tableExp10(diff, &y) 93 | y.QuoRem(&d.Coeff, e, &m) 94 | if m.Sign() != 0 { 95 | res |= Inexact 96 | var discard Decimal 97 | discard.Coeff.Set(&m) 98 | discard.Exponent = int32(-diff) 99 | if r.ShouldAddOne(&y, x.Negative, discard.Cmp(decimalHalf)) { 100 | roundAddOne(&y, &diff) 101 | } 102 | } 103 | d.Coeff.Set(&y) 104 | // The coefficient changed, so recompute num digits in setExponent. 105 | nd = unknownNumDigits 106 | } else { 107 | diff = 0 108 | } 109 | res |= d.setExponent(c, nd, res, int64(d.Exponent), diff) 110 | return res 111 | } 112 | 113 | // roundAddOne adds 1 to abs(b). 114 | func roundAddOne(b *BigInt, diff *int64) { 115 | if b.Sign() < 0 { 116 | panic("unexpected negative") 117 | } 118 | nd := NumDigits(b) 119 | b.Add(b, bigOne) 120 | nd2 := NumDigits(b) 121 | if nd2 > nd { 122 | b.Quo(b, bigTen) 123 | *diff++ 124 | } 125 | } 126 | 127 | // roundings is a set containing all available Rounders. 128 | var roundings = map[Rounder]struct{}{ 129 | RoundDown: {}, 130 | RoundHalfUp: {}, 131 | RoundHalfEven: {}, 132 | RoundCeiling: {}, 133 | RoundFloor: {}, 134 | RoundHalfDown: {}, 135 | RoundUp: {}, 136 | Round05Up: {}, 137 | } 138 | 139 | const ( 140 | // RoundDown rounds toward 0; truncate. 141 | RoundDown Rounder = "down" 142 | // RoundHalfUp rounds up if the digits are >= 0.5. 143 | RoundHalfUp Rounder = "half_up" 144 | // RoundHalfEven rounds up if the digits are > 0.5. If the digits are equal 145 | // to 0.5, it rounds up if the previous digit is odd, always producing an 146 | // even digit. 147 | RoundHalfEven Rounder = "half_even" 148 | // RoundCeiling towards +Inf: rounds up if digits are > 0 and the number 149 | // is positive. 150 | RoundCeiling Rounder = "ceiling" 151 | // RoundFloor towards -Inf: rounds up if digits are > 0 and the number 152 | // is negative. 153 | RoundFloor Rounder = "floor" 154 | // RoundHalfDown rounds up if the digits are > 0.5. 155 | RoundHalfDown Rounder = "half_down" 156 | // RoundUp rounds away from 0. 157 | RoundUp Rounder = "up" 158 | // Round05Up rounds zero or five away from 0; same as round-up, except that 159 | // rounding up only occurs if the digit to be rounded up is 0 or 5. 160 | Round05Up Rounder = "05up" 161 | ) 162 | 163 | func roundDown(result *BigInt, neg bool, half int) bool { 164 | return false 165 | } 166 | 167 | func roundUp(result *BigInt, neg bool, half int) bool { 168 | return true 169 | } 170 | 171 | func round05Up(result *BigInt, neg bool, half int) bool { 172 | var z BigInt 173 | z.Rem(result, bigFive) 174 | if z.Sign() == 0 { 175 | return true 176 | } 177 | z.Rem(result, bigTen) 178 | return z.Sign() == 0 179 | } 180 | 181 | func roundHalfUp(result *BigInt, neg bool, half int) bool { 182 | return half >= 0 183 | } 184 | 185 | func roundHalfEven(result *BigInt, neg bool, half int) bool { 186 | if half > 0 { 187 | return true 188 | } 189 | if half < 0 { 190 | return false 191 | } 192 | return result.Bit(0) == 1 193 | } 194 | 195 | func roundHalfDown(result *BigInt, neg bool, half int) bool { 196 | return half > 0 197 | } 198 | 199 | func roundFloor(result *BigInt, neg bool, half int) bool { 200 | return neg 201 | } 202 | 203 | func roundCeiling(result *BigInt, neg bool, half int) bool { 204 | return !neg 205 | } 206 | -------------------------------------------------------------------------------- /sql_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | //go:build sql 16 | // +build sql 17 | 18 | package apd 19 | 20 | import ( 21 | "database/sql" 22 | "flag" 23 | "testing" 24 | 25 | _ "github.com/lib/pq" 26 | ) 27 | 28 | var ( 29 | flagPostgres = flag.String("postgres", "postgres://postgres@localhost/apd?sslmode=disable", "Postgres connection string to an empty database") 30 | ) 31 | 32 | // TestSQL tests the Scan and Value methods of Decimal. 33 | func TestSQL(t *testing.T) { 34 | db, err := sql.Open("postgres", *flagPostgres) 35 | if err != nil { 36 | t.Fatal(err) 37 | } 38 | var a Decimal 39 | if _, _, err = a.SetString("1234.567e5"); err != nil { 40 | t.Fatal(err) 41 | } 42 | if _, err := db.Exec("drop table if exists d"); err != nil { 43 | t.Fatal(err) 44 | } 45 | if _, err := db.Exec("create table d (v decimal)"); err != nil { 46 | t.Fatal(err) 47 | } 48 | if _, err := db.Exec("insert into d values ($1)", a); err != nil { 49 | t.Fatal(err) 50 | } 51 | if _, err := db.Exec("update d set v = v + 1e5"); err != nil { 52 | t.Fatal(err) 53 | } 54 | var b, c, d Decimal 55 | var nd NullDecimal 56 | if err := db.QueryRow("select v, v::text, v::int, v::float, v from d").Scan(&a, &b, &c, &d, &nd); err != nil { 57 | t.Fatal(err) 58 | } 59 | want, _, err := NewFromString("123556700") 60 | if err != nil { 61 | t.Fatal(err) 62 | } 63 | for i, v := range []*Decimal{&a, &b, &c, &d, &nd.Decimal} { 64 | if v.Cmp(want) != 0 { 65 | t.Fatalf("%d: unexpected: %s, want: %s", i, v.String(), want.String()) 66 | } 67 | } 68 | 69 | if _, err := db.Exec("update d set v = NULL"); err != nil { 70 | t.Fatal(err) 71 | } 72 | if err := db.QueryRow("select v from d").Scan(&nd); err != nil { 73 | t.Fatal(err) 74 | } 75 | if nd.Valid { 76 | t.Fatal("expected null") 77 | } 78 | 79 | var g Decimal 80 | if err := db.QueryRow("select 0::decimal(19,9)").Scan(&g); err != nil { 81 | t.Fatal(err) 82 | } 83 | zeroD, _, err := NewFromString("0.000000000") 84 | if err != nil { 85 | t.Fatal(err) 86 | } 87 | if g.String() != zeroD.String() { 88 | t.Fatalf("expected 0::decimal(19.9) pg value %s match, found %s", g.String(), zeroD.String()) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /table.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | // digitsLookupTable is used to map binary digit counts to their corresponding 18 | // decimal border values. The map relies on the proof that (without leading zeros) 19 | // for any given number of binary digits r, such that the number represented is 20 | // between 2^r and 2^(r+1)-1, there are only two possible decimal digit counts 21 | // k and k+1 that the binary r digits could be representing. 22 | // 23 | // Using this proof, for a given digit count, the map will return the lower number 24 | // of decimal digits (k) the binary digit count could represent, along with the 25 | // value of the border between the two decimal digit counts (10^k). 26 | const digitsTableSize = 128 27 | 28 | var digitsLookupTable [digitsTableSize + 1]tableVal 29 | 30 | type tableVal struct { 31 | digits int64 32 | border BigInt 33 | nborder BigInt 34 | } 35 | 36 | func init() { 37 | curVal := NewBigInt(1) 38 | curExp := new(BigInt) 39 | for i := 1; i <= digitsTableSize; i++ { 40 | if i > 1 { 41 | curVal.Lsh(curVal, 1) 42 | } 43 | 44 | elem := &digitsLookupTable[i] 45 | elem.digits = int64(len(curVal.String())) 46 | 47 | elem.border.SetInt64(10) 48 | curExp.SetInt64(elem.digits) 49 | elem.border.Exp(&elem.border, curExp, nil) 50 | elem.nborder.Neg(&elem.border) 51 | } 52 | } 53 | 54 | // NumDigits returns the number of decimal digits of d.Coeff. 55 | //gcassert:inline 56 | func (d *Decimal) NumDigits() int64 { 57 | return NumDigits(&d.Coeff) 58 | } 59 | 60 | // NumDigits returns the number of decimal digits of b. 61 | func NumDigits(b *BigInt) int64 { 62 | bl := b.BitLen() 63 | if bl == 0 { 64 | return 1 65 | } 66 | 67 | if bl <= digitsTableSize { 68 | val := &digitsLookupTable[bl] 69 | // In general, we either have val.digits or val.digits+1 digits and we have 70 | // to compare with the border value. But that's not true for all values of 71 | // bl: in particular, if bl+1 maps to the same number of digits, then we 72 | // know for sure we have val.digits and we can skip the comparison. 73 | // This is the case for about 2 out of 3 values. 74 | if bl < digitsTableSize && digitsLookupTable[bl+1].digits == val.digits { 75 | return val.digits 76 | } 77 | 78 | switch b.Sign() { 79 | case 1: 80 | if b.Cmp(&val.border) < 0 { 81 | return val.digits 82 | } 83 | case -1: 84 | if b.Cmp(&val.nborder) > 0 { 85 | return val.digits 86 | } 87 | } 88 | return val.digits + 1 89 | } 90 | 91 | n := int64(float64(bl) / digitsToBitsRatio) 92 | var tmp BigInt 93 | e := tableExp10(n, &tmp) 94 | var a *BigInt 95 | if b.Sign() < 0 { 96 | var tmpA BigInt 97 | a := &tmpA 98 | a.Abs(b) 99 | } else { 100 | a = b 101 | } 102 | if a.Cmp(e) >= 0 { 103 | n++ 104 | } 105 | return n 106 | } 107 | 108 | // powerTenTableSize is the magnitude of the maximum power of 10 exponent that 109 | // is stored in the pow10LookupTable. For instance, if the powerTenTableSize 110 | // if 3, then the lookup table will store power of 10 values from 10^0 to 111 | // 10^3 inclusive. 112 | const powerTenTableSize = 128 113 | 114 | var pow10LookupTable [powerTenTableSize + 1]BigInt 115 | 116 | func init() { 117 | for i := int64(0); i <= powerTenTableSize; i++ { 118 | setBigWithPow(&pow10LookupTable[i], i) 119 | } 120 | } 121 | 122 | func setBigWithPow(res *BigInt, pow int64) { 123 | var tmp BigInt 124 | tmp.SetInt64(pow) 125 | res.Exp(bigTen, &tmp, nil) 126 | } 127 | 128 | // tableExp10 returns 10^x for x >= 0, looked up from a table when 129 | // possible. This returned value must not be mutated. tmp is used as an 130 | // intermediate variable and must not be nil. 131 | func tableExp10(x int64, tmp *BigInt) *BigInt { 132 | if x <= powerTenTableSize { 133 | return &pow10LookupTable[x] 134 | } 135 | setBigWithPow(tmp, x) 136 | return tmp 137 | } 138 | -------------------------------------------------------------------------------- /table_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Cockroach Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | // implied. See the License for the specific language governing 13 | // permissions and limitations under the License. 14 | 15 | package apd 16 | 17 | import ( 18 | "bytes" 19 | "math/rand" 20 | "strings" 21 | "testing" 22 | ) 23 | 24 | func BenchmarkNumDigitsLookup(b *testing.B) { 25 | prep := func(start string, c byte) []*Decimal { 26 | var ds []*Decimal 27 | buf := bytes.NewBufferString(start) 28 | for i := 1; i < digitsTableSize; i++ { 29 | buf.WriteByte(c) 30 | d, _, _ := NewFromString(buf.String()) 31 | ds = append(ds, d) 32 | } 33 | return ds 34 | } 35 | var ds []*Decimal 36 | ds = append(ds, prep("", '9')...) 37 | ds = append(ds, prep("1", '0')...) 38 | ds = append(ds, prep("-", '9')...) 39 | ds = append(ds, prep("-1", '0')...) 40 | b.ResetTimer() 41 | for i := 0; i < b.N; i++ { 42 | for _, d := range ds { 43 | d.NumDigits() 44 | } 45 | } 46 | } 47 | 48 | func BenchmarkNumDigitsFull(b *testing.B) { 49 | prep := func(start string, c byte) []*Decimal { 50 | var ds []*Decimal 51 | buf := bytes.NewBufferString(start) 52 | for i := 1; i < 1000; i++ { 53 | buf.WriteByte(c) 54 | d, _, _ := NewFromString(buf.String()) 55 | ds = append(ds, d) 56 | } 57 | return ds 58 | } 59 | var ds []*Decimal 60 | ds = append(ds, prep("", '9')...) 61 | ds = append(ds, prep("1", '0')...) 62 | ds = append(ds, prep("-", '9')...) 63 | ds = append(ds, prep("-1", '0')...) 64 | b.ResetTimer() 65 | for i := 0; i < b.N; i++ { 66 | for _, d := range ds { 67 | d.NumDigits() 68 | } 69 | } 70 | } 71 | 72 | func TestNumDigits(t *testing.T) { 73 | runTest := func(start string, c byte) { 74 | buf := bytes.NewBufferString(start) 75 | var offset int 76 | if strings.HasPrefix(start, "-") { 77 | offset-- 78 | } 79 | for i := 1; i < 1000; i++ { 80 | buf.WriteByte(c) 81 | bs := buf.String() 82 | t.Run(bs, func(t *testing.T) { 83 | d := newDecimal(t, testCtx, bs) 84 | n := d.NumDigits() 85 | e := int64(buf.Len() + offset) 86 | if n != e { 87 | t.Fatalf("%s ('%c'): expected %d, got %d", bs, c, e, n) 88 | } 89 | }) 90 | } 91 | } 92 | runTest("", '9') 93 | runTest("1", '0') 94 | runTest("-", '9') 95 | runTest("-1", '0') 96 | } 97 | 98 | func TestDigitsLookupTable(t *testing.T) { 99 | // Make sure all elements in table make sense. 100 | min := new(BigInt) 101 | prevBorder := NewBigInt(0) 102 | for i := 1; i <= digitsTableSize; i++ { 103 | elem := &digitsLookupTable[i] 104 | 105 | min.SetInt64(2) 106 | min.Exp(min, NewBigInt(int64(i-1)), nil) 107 | if minLen := int64(len(min.String())); minLen != elem.digits { 108 | t.Errorf("expected 2^%d to have %d digits, found %d", i, elem.digits, minLen) 109 | } 110 | 111 | if zeros := int64(strings.Count(elem.border.String(), "0")); zeros != elem.digits { 112 | t.Errorf("the %d digits for digitsLookupTable[%d] does not agree with the border %v", elem.digits, i, &elem.border) 113 | } 114 | 115 | if min.Cmp(&elem.border) >= 0 { 116 | t.Errorf("expected 2^%d = %v to be less than the border, found %v", i-1, min, &elem.border) 117 | } 118 | 119 | if elem.border.Cmp(prevBorder) > 0 { 120 | if min.Cmp(prevBorder) <= 0 { 121 | t.Errorf("expected 2^%d = %v to be greater than or equal to the border, found %v", i-1, min, prevBorder) 122 | } 123 | prevBorder = &elem.border 124 | } 125 | } 126 | 127 | // Throw random big.Ints at the table and make sure the 128 | // digit lengths line up. 129 | const randomTrials = 100 130 | for i := 0; i < randomTrials; i++ { 131 | a := NewBigInt(rand.Int63()) 132 | b := NewBigInt(rand.Int63()) 133 | a.Mul(a, b) 134 | 135 | d := NewWithBigInt(a, 0) 136 | tableDigits := d.NumDigits() 137 | if actualDigits := int64(len(a.String())); actualDigits != tableDigits { 138 | t.Errorf("expected %d digits for %v, found %d", tableDigits, a, actualDigits) 139 | } 140 | } 141 | } 142 | 143 | func TestTableExp10(t *testing.T) { 144 | tests := []struct { 145 | pow int64 146 | str string 147 | }{ 148 | { 149 | pow: 0, 150 | str: "1", 151 | }, 152 | { 153 | pow: 1, 154 | str: "10", 155 | }, 156 | { 157 | pow: 5, 158 | str: "100000", 159 | }, 160 | { 161 | pow: powerTenTableSize + 1, 162 | str: "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 163 | }, 164 | } 165 | 166 | for i, test := range tests { 167 | var tmpE BigInt 168 | d := tableExp10(test.pow, &tmpE) 169 | if s := d.String(); s != test.str { 170 | t.Errorf("%d: expected PowerOfTenDec(%d) to give %s, got %s", i, test.pow, test.str, s) 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /testdata/abs.decTest: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------ 2 | -- abs.decTest -- decimal absolute value -- 3 | -- Copyright (c) Mike Cowlishaw, 1981, 2010. All rights reserved. -- 4 | -- Parts copyright (c) IBM Corporation, 1981, 2008. -- 5 | ------------------------------------------------------------------------ 6 | -- Please see the document "General Decimal Arithmetic Testcases" -- 7 | -- at http://speleotrove.com/decimal for the description of -- 8 | -- these testcases. -- 9 | -- -- 10 | -- These testcases are experimental ('beta' versions), and they -- 11 | -- may contain errors. They are offered on an as-is basis. In -- 12 | -- particular, achieving the same results as the tests here is not -- 13 | -- a guarantee that an implementation complies with any Standard -- 14 | -- or specification. The tests are not exhaustive. -- 15 | -- -- 16 | -- Please send comments, suggestions, and corrections to the author: -- 17 | -- Mike Cowlishaw, mfc@speleotrove.com -- 18 | ------------------------------------------------------------------------ 19 | version: 2.62 20 | 21 | -- This set of tests primarily tests the existence of the operator. 22 | -- Additon, subtraction, rounding, and more overflows are tested 23 | -- elsewhere. 24 | 25 | precision: 9 26 | rounding: half_up 27 | maxExponent: 384 28 | minexponent: -383 29 | extended: 1 30 | 31 | absx001 abs '1' -> '1' 32 | absx002 abs '-1' -> '1' 33 | absx003 abs '1.00' -> '1.00' 34 | absx004 abs '-1.00' -> '1.00' 35 | absx005 abs '0' -> '0' 36 | absx006 abs '0.00' -> '0.00' 37 | absx007 abs '00.0' -> '0.0' 38 | absx008 abs '00.00' -> '0.00' 39 | absx009 abs '00' -> '0' 40 | 41 | absx010 abs '-2' -> '2' 42 | absx011 abs '2' -> '2' 43 | absx012 abs '-2.00' -> '2.00' 44 | absx013 abs '2.00' -> '2.00' 45 | absx014 abs '-0' -> '0' 46 | absx015 abs '-0.00' -> '0.00' 47 | absx016 abs '-00.0' -> '0.0' 48 | absx017 abs '-00.00' -> '0.00' 49 | absx018 abs '-00' -> '0' 50 | 51 | absx020 abs '-2000000' -> '2000000' 52 | absx021 abs '2000000' -> '2000000' 53 | precision: 7 54 | absx022 abs '-2000000' -> '2000000' 55 | absx023 abs '2000000' -> '2000000' 56 | precision: 6 57 | absx024 abs '-2000000' -> '2.00000E+6' Rounded 58 | absx025 abs '2000000' -> '2.00000E+6' Rounded 59 | precision: 3 60 | absx026 abs '-2000000' -> '2.00E+6' Rounded 61 | absx027 abs '2000000' -> '2.00E+6' Rounded 62 | 63 | absx030 abs '+0.1' -> '0.1' 64 | absx031 abs '-0.1' -> '0.1' 65 | absx032 abs '+0.01' -> '0.01' 66 | absx033 abs '-0.01' -> '0.01' 67 | absx034 abs '+0.001' -> '0.001' 68 | absx035 abs '-0.001' -> '0.001' 69 | absx036 abs '+0.000001' -> '0.000001' 70 | absx037 abs '-0.000001' -> '0.000001' 71 | absx038 abs '+0.000000000001' -> '1E-12' 72 | absx039 abs '-0.000000000001' -> '1E-12' 73 | 74 | -- examples from decArith 75 | precision: 9 76 | absx040 abs '2.1' -> '2.1' 77 | absx041 abs '-100' -> '100' 78 | absx042 abs '101.5' -> '101.5' 79 | absx043 abs '-101.5' -> '101.5' 80 | 81 | -- more fixed, potential LHS swaps/overlays if done by subtract 0 82 | precision: 9 83 | absx060 abs '-56267E-10' -> '0.0000056267' 84 | absx061 abs '-56267E-5' -> '0.56267' 85 | absx062 abs '-56267E-2' -> '562.67' 86 | absx063 abs '-56267E-1' -> '5626.7' 87 | absx065 abs '-56267E-0' -> '56267' 88 | 89 | -- overflow tests 90 | maxexponent: 999999999 91 | minexponent: -999999999 92 | precision: 3 93 | absx120 abs 9.999E+999999999 -> Infinity Inexact Overflow Rounded 94 | 95 | -- subnormals and underflow 96 | precision: 3 97 | maxexponent: 999 98 | minexponent: -999 99 | absx210 abs 1.00E-999 -> 1.00E-999 100 | absx211 abs 0.1E-999 -> 1E-1000 Subnormal 101 | absx212 abs 0.10E-999 -> 1.0E-1000 Subnormal 102 | absx213 abs 0.100E-999 -> 1.0E-1000 Subnormal Rounded 103 | absx214 abs 0.01E-999 -> 1E-1001 Subnormal 104 | -- next is rounded to Emin 105 | absx215 abs 0.999E-999 -> 1.00E-999 Inexact Rounded Subnormal Underflow 106 | absx216 abs 0.099E-999 -> 1.0E-1000 Inexact Rounded Subnormal Underflow 107 | absx217 abs 0.009E-999 -> 1E-1001 Inexact Rounded Subnormal Underflow 108 | absx218 abs 0.001E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 109 | absx219 abs 0.0009E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 110 | absx220 abs 0.0001E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 111 | 112 | absx230 abs -1.00E-999 -> 1.00E-999 113 | absx231 abs -0.1E-999 -> 1E-1000 Subnormal 114 | absx232 abs -0.10E-999 -> 1.0E-1000 Subnormal 115 | absx233 abs -0.100E-999 -> 1.0E-1000 Subnormal Rounded 116 | absx234 abs -0.01E-999 -> 1E-1001 Subnormal 117 | -- next is rounded to Emin 118 | absx235 abs -0.999E-999 -> 1.00E-999 Inexact Rounded Subnormal Underflow 119 | absx236 abs -0.099E-999 -> 1.0E-1000 Inexact Rounded Subnormal Underflow 120 | absx237 abs -0.009E-999 -> 1E-1001 Inexact Rounded Subnormal Underflow 121 | absx238 abs -0.001E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 122 | absx239 abs -0.0009E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 123 | absx240 abs -0.0001E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 124 | 125 | -- long operand tests 126 | maxexponent: 999 127 | minexponent: -999 128 | precision: 9 129 | absx301 abs 12345678000 -> 1.23456780E+10 Rounded 130 | absx302 abs 1234567800 -> 1.23456780E+9 Rounded 131 | absx303 abs 1234567890 -> 1.23456789E+9 Rounded 132 | absx304 abs 1234567891 -> 1.23456789E+9 Inexact Rounded 133 | absx305 abs 12345678901 -> 1.23456789E+10 Inexact Rounded 134 | absx306 abs 1234567896 -> 1.23456790E+9 Inexact Rounded 135 | 136 | precision: 15 137 | absx321 abs 12345678000 -> 12345678000 138 | absx322 abs 1234567800 -> 1234567800 139 | absx323 abs 1234567890 -> 1234567890 140 | absx324 abs 1234567891 -> 1234567891 141 | absx325 abs 12345678901 -> 12345678901 142 | absx326 abs 1234567896 -> 1234567896 143 | 144 | 145 | -- Specials 146 | precision: 9 147 | 148 | -- specials 149 | absx520 abs 'Inf' -> 'Infinity' 150 | absx521 abs '-Inf' -> 'Infinity' 151 | absx522 abs NaN -> NaN 152 | absx523 abs sNaN -> NaN Invalid_operation 153 | absx524 abs NaN22 -> NaN22 154 | absx525 abs sNaN33 -> NaN33 Invalid_operation 155 | absx526 abs -NaN22 -> -NaN22 156 | absx527 abs -sNaN33 -> -NaN33 Invalid_operation 157 | 158 | -- Null tests 159 | absx900 abs # -> NaN Invalid_operation 160 | 161 | -------------------------------------------------------------------------------- /testdata/cuberoot-apd.decTest: -------------------------------------------------------------------------------- 1 | -- cuberoot-apd.decTest -- decimal cube root 2 | 3 | -- These tests are not part of the GDA test suite, but were written for 4 | -- apd. They are not as exhaustive as those tests, but do cover a number of 5 | -- useful results. 6 | 7 | extended: 0 8 | precision: 9 9 | rounding: half_up 10 | maxExponent: 999 11 | minExponent: -999 12 | 13 | -- basics 14 | cbtx001 cuberoot 1 -> 1 15 | cbtx002 cuberoot -1 -> -1 16 | cbtx003 cuberoot 1.00 -> 1.0 17 | cbtx004 cuberoot -1.00 -> -1.0 18 | cbtx005 cuberoot 0 -> 0 19 | cbtx006 cuberoot 00.0 -> 0 20 | cbtx007 cuberoot 0.00 -> 0 21 | cbtx008 cuberoot 00.00 -> 0 22 | cbtx009 cuberoot 00 -> 0 23 | 24 | cbtx010 cuberoot -2 -> -1.25992105 Inexact Rounded 25 | cbtx011 cuberoot 2 -> 1.25992105 Inexact Rounded 26 | cbtx012 cuberoot -2.00 -> -1.25992105 Inexact Rounded 27 | cbtx013 cuberoot 2.00 -> 1.25992105 Inexact Rounded 28 | cbtx014 cuberoot -0 -> -0 29 | cbtx015 cuberoot -0.00 -> -0.0 30 | cbtx016 cuberoot -00.0 -> -0.0 31 | cbtx017 cuberoot -0E+9 -> -0E+3 32 | cbtx018 cuberoot -0E+10 -> -0E+3 33 | cbtx019 cuberoot -0E+11 -> -0E+3 34 | cbtx020 cuberoot -0E+12 -> -0E+4 35 | cbtx021 cuberoot -00 -> -0 36 | cbtx022 cuberoot 0E+5 -> 0 37 | cbtx023 cuberoot 8.0 -> 2.0 38 | cbtx024 cuberoot 8.00 -> 2.0 39 | 40 | cbtx030 cuberoot +0.1 -> 0.464158883 Inexact Rounded 41 | cbtx031 cuberoot -0.1 -> -0.464158883 Inexact Rounded 42 | cbtx032 cuberoot +0.01 -> 0.215443469 Inexact Rounded 43 | cbtx033 cuberoot -0.01 -> -0.215443469 Inexact Rounded 44 | cbtx034 cuberoot +0.001 -> 0.1 45 | cbtx035 cuberoot -0.001 -> -0.1 46 | cbtx036 cuberoot +0.000001 -> 0.01 47 | cbtx037 cuberoot -0.000001 -> -0.01 48 | cbtx038 cuberoot +0.000000000001 -> 0.0001 49 | cbtx039 cuberoot -0.000000000001 -> -0.0001 50 | 51 | cbtx041 cuberoot 1.1 -> 1.03228012 Inexact Rounded 52 | cbtx042 cuberoot 1.10 -> 1.03228012 Inexact Rounded 53 | cbtx043 cuberoot 1.100 -> 1.03228012 Inexact Rounded 54 | cbtx044 cuberoot 1.110 -> 1.03539881 Inexact Rounded 55 | cbtx045 cuberoot -1.1 -> -1.03228012 Inexact Rounded 56 | cbtx046 cuberoot -1.10 -> -1.03228012 Inexact Rounded 57 | cbtx047 cuberoot -1.100 -> -1.03228012 Inexact Rounded 58 | cbtx048 cuberoot -1.110 -> -1.03539881 Inexact Rounded 59 | cbtx049 cuberoot 9.9 -> 2.14722917 Inexact Rounded 60 | cbtx050 cuberoot 9.90 -> 2.14722917 Inexact Rounded 61 | cbtx051 cuberoot 9.900 -> 2.14722917 Inexact Rounded 62 | cbtx052 cuberoot 9.990 -> 2.15371631 Inexact Rounded 63 | cbtx053 cuberoot -9.9 -> -2.14722917 Inexact Rounded 64 | cbtx054 cuberoot -9.90 -> -2.14722917 Inexact Rounded 65 | cbtx055 cuberoot -9.900 -> -2.14722917 Inexact Rounded 66 | cbtx056 cuberoot -9.990 -> -2.15371631 Inexact Rounded 67 | 68 | cbtx060 cuberoot 10.0 -> 2.15443469 Inexact Rounded 69 | cbtx061 cuberoot 10.00 -> 2.15443469 Inexact Rounded 70 | cbtx062 cuberoot 1000.0 -> 10.0 71 | cbtx063 cuberoot 1000.00 -> 10.0 72 | cbtx064 cuberoot 1.1000E+3 -> 10.3228012 Inexact Rounded 73 | cbtx065 cuberoot 1.10000E+3 -> 10.3228012 Inexact Rounded 74 | cbtx066 cuberoot -10.0 -> -2.15443469 Inexact Rounded 75 | cbtx067 cuberoot -10.00 -> -2.15443469 Inexact Rounded 76 | cbtx068 cuberoot -1000.0 -> -10.0 77 | cbtx069 cuberoot -1000.00 -> -10.0 78 | cbtx070 cuberoot -1.1000E+3 -> -10.3228012 Inexact Rounded 79 | cbtx071 cuberoot -1.10000E+3 -> -10.3228012 Inexact Rounded 80 | 81 | -- famous cubes 82 | cbtx080 cuberoot 1 -> 1 83 | cbtx081 cuberoot 8 -> 2 84 | cbtx082 cuberoot 27 -> 3 85 | cbtx083 cuberoot 64 -> 4 86 | cbtx084 cuberoot 125 -> 5 87 | cbtx085 cuberoot 216 -> 6 88 | cbtx086 cuberoot 343 -> 7 89 | cbtx087 cuberoot 512 -> 8 90 | cbtx088 cuberoot 729 -> 9 91 | cbtx089 cuberoot 1000 -> 10 92 | 93 | -- others 94 | precision: 5 95 | 96 | cbtx100 cuberoot 1.0001 -> 1.0000 Inexact Rounded 97 | -------------------------------------------------------------------------------- /testdata/divideint.decTest: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------ 2 | -- divideint.decTest -- decimal integer division -- 3 | -- Copyright (c) Mike Cowlishaw, 1981, 2010. All rights reserved. -- 4 | -- Parts copyright (c) IBM Corporation, 1981, 2008. -- 5 | ------------------------------------------------------------------------ 6 | -- Please see the document "General Decimal Arithmetic Testcases" -- 7 | -- at http://speleotrove.com/decimal for the description of -- 8 | -- these testcases. -- 9 | -- -- 10 | -- These testcases are experimental ('beta' versions), and they -- 11 | -- may contain errors. They are offered on an as-is basis. In -- 12 | -- particular, achieving the same results as the tests here is not -- 13 | -- a guarantee that an implementation complies with any Standard -- 14 | -- or specification. The tests are not exhaustive. -- 15 | -- -- 16 | -- Please send comments, suggestions, and corrections to the author: -- 17 | -- Mike Cowlishaw, mfc@speleotrove.com -- 18 | ------------------------------------------------------------------------ 19 | version: 2.62 20 | 21 | extended: 1 22 | precision: 9 23 | rounding: half_up 24 | maxExponent: 384 25 | minexponent: -383 26 | 27 | dvix001 divideint 1 1 -> 1 28 | dvix002 divideint 2 1 -> 2 29 | dvix003 divideint 1 2 -> 0 30 | dvix004 divideint 2 2 -> 1 31 | dvix005 divideint 0 1 -> 0 32 | dvix006 divideint 0 2 -> 0 33 | dvix007 divideint 1 3 -> 0 34 | dvix008 divideint 2 3 -> 0 35 | dvix009 divideint 3 3 -> 1 36 | 37 | dvix010 divideint 2.4 1 -> 2 38 | dvix011 divideint 2.4 -1 -> -2 39 | dvix012 divideint -2.4 1 -> -2 40 | dvix013 divideint -2.4 -1 -> 2 41 | dvix014 divideint 2.40 1 -> 2 42 | dvix015 divideint 2.400 1 -> 2 43 | dvix016 divideint 2.4 2 -> 1 44 | dvix017 divideint 2.400 2 -> 1 45 | dvix018 divideint 2. 2 -> 1 46 | dvix019 divideint 20 20 -> 1 47 | 48 | dvix020 divideint 187 187 -> 1 49 | dvix021 divideint 5 2 -> 2 50 | dvix022 divideint 5 2.0 -> 2 51 | dvix023 divideint 5 2.000 -> 2 52 | dvix024 divideint 5 0.200 -> 25 53 | dvix025 divideint 5 0.200 -> 25 54 | 55 | dvix030 divideint 1 2 -> 0 56 | dvix031 divideint 1 4 -> 0 57 | dvix032 divideint 1 8 -> 0 58 | dvix033 divideint 1 16 -> 0 59 | dvix034 divideint 1 32 -> 0 60 | dvix035 divideint 1 64 -> 0 61 | dvix040 divideint 1 -2 -> -0 62 | dvix041 divideint 1 -4 -> -0 63 | dvix042 divideint 1 -8 -> -0 64 | dvix043 divideint 1 -16 -> -0 65 | dvix044 divideint 1 -32 -> -0 66 | dvix045 divideint 1 -64 -> -0 67 | dvix050 divideint -1 2 -> -0 68 | dvix051 divideint -1 4 -> -0 69 | dvix052 divideint -1 8 -> -0 70 | dvix053 divideint -1 16 -> -0 71 | dvix054 divideint -1 32 -> -0 72 | dvix055 divideint -1 64 -> -0 73 | dvix060 divideint -1 -2 -> 0 74 | dvix061 divideint -1 -4 -> 0 75 | dvix062 divideint -1 -8 -> 0 76 | dvix063 divideint -1 -16 -> 0 77 | dvix064 divideint -1 -32 -> 0 78 | dvix065 divideint -1 -64 -> 0 79 | 80 | -- similar with powers of ten 81 | dvix160 divideint 1 1 -> 1 82 | dvix161 divideint 1 10 -> 0 83 | dvix162 divideint 1 100 -> 0 84 | dvix163 divideint 1 1000 -> 0 85 | dvix164 divideint 1 10000 -> 0 86 | dvix165 divideint 1 100000 -> 0 87 | dvix166 divideint 1 1000000 -> 0 88 | dvix167 divideint 1 10000000 -> 0 89 | dvix168 divideint 1 100000000 -> 0 90 | dvix170 divideint 1 -1 -> -1 91 | dvix171 divideint 1 -10 -> -0 92 | dvix172 divideint 1 -100 -> -0 93 | dvix173 divideint 1 -1000 -> -0 94 | dvix174 divideint 1 -10000 -> -0 95 | dvix175 divideint 1 -100000 -> -0 96 | dvix176 divideint 1 -1000000 -> -0 97 | dvix177 divideint 1 -10000000 -> -0 98 | dvix178 divideint 1 -100000000 -> -0 99 | dvix180 divideint -1 1 -> -1 100 | dvix181 divideint -1 10 -> -0 101 | dvix182 divideint -1 100 -> -0 102 | dvix183 divideint -1 1000 -> -0 103 | dvix184 divideint -1 10000 -> -0 104 | dvix185 divideint -1 100000 -> -0 105 | dvix186 divideint -1 1000000 -> -0 106 | dvix187 divideint -1 10000000 -> -0 107 | dvix188 divideint -1 100000000 -> -0 108 | dvix190 divideint -1 -1 -> 1 109 | dvix191 divideint -1 -10 -> 0 110 | dvix192 divideint -1 -100 -> 0 111 | dvix193 divideint -1 -1000 -> 0 112 | dvix194 divideint -1 -10000 -> 0 113 | dvix195 divideint -1 -100000 -> 0 114 | dvix196 divideint -1 -1000000 -> 0 115 | dvix197 divideint -1 -10000000 -> 0 116 | dvix198 divideint -1 -100000000 -> 0 117 | 118 | -- some long operand cases here 119 | dvix070 divideint 999999999 1 -> 999999999 120 | dvix071 divideint 999999999.4 1 -> 999999999 121 | dvix072 divideint 999999999.5 1 -> 999999999 122 | dvix073 divideint 999999999.9 1 -> 999999999 123 | dvix074 divideint 999999999.999 1 -> 999999999 124 | precision: 6 125 | dvix080 divideint 999999999 1 -> NaN Division_impossible 126 | dvix081 divideint 99999999 1 -> NaN Division_impossible 127 | dvix082 divideint 9999999 1 -> NaN Division_impossible 128 | dvix083 divideint 999999 1 -> 999999 129 | dvix084 divideint 99999 1 -> 99999 130 | dvix085 divideint 9999 1 -> 9999 131 | dvix086 divideint 999 1 -> 999 132 | dvix087 divideint 99 1 -> 99 133 | dvix088 divideint 9 1 -> 9 134 | 135 | precision: 9 136 | dvix090 divideint 0. 1 -> 0 137 | dvix091 divideint .0 1 -> 0 138 | dvix092 divideint 0.00 1 -> 0 139 | dvix093 divideint 0.00E+9 1 -> 0 140 | dvix094 divideint 0.0000E-50 1 -> 0 141 | 142 | dvix100 divideint 1 1 -> 1 143 | dvix101 divideint 1 2 -> 0 144 | dvix102 divideint 1 3 -> 0 145 | dvix103 divideint 1 4 -> 0 146 | dvix104 divideint 1 5 -> 0 147 | dvix105 divideint 1 6 -> 0 148 | dvix106 divideint 1 7 -> 0 149 | dvix107 divideint 1 8 -> 0 150 | dvix108 divideint 1 9 -> 0 151 | dvix109 divideint 1 10 -> 0 152 | dvix110 divideint 1 1 -> 1 153 | dvix111 divideint 2 1 -> 2 154 | dvix112 divideint 3 1 -> 3 155 | dvix113 divideint 4 1 -> 4 156 | dvix114 divideint 5 1 -> 5 157 | dvix115 divideint 6 1 -> 6 158 | dvix116 divideint 7 1 -> 7 159 | dvix117 divideint 8 1 -> 8 160 | dvix118 divideint 9 1 -> 9 161 | dvix119 divideint 10 1 -> 10 162 | 163 | -- from DiagBigDecimal 164 | dvix131 divideint 101.3 1 -> 101 165 | dvix132 divideint 101.0 1 -> 101 166 | dvix133 divideint 101.3 3 -> 33 167 | dvix134 divideint 101.0 3 -> 33 168 | dvix135 divideint 2.4 1 -> 2 169 | dvix136 divideint 2.400 1 -> 2 170 | dvix137 divideint 18 18 -> 1 171 | dvix138 divideint 1120 1000 -> 1 172 | dvix139 divideint 2.4 2 -> 1 173 | dvix140 divideint 2.400 2 -> 1 174 | dvix141 divideint 0.5 2.000 -> 0 175 | dvix142 divideint 8.005 7 -> 1 176 | dvix143 divideint 5 2 -> 2 177 | dvix144 divideint 0 2 -> 0 178 | dvix145 divideint 0.00 2 -> 0 179 | 180 | -- Others 181 | dvix150 divideint 12345 4.999 -> 2469 182 | dvix151 divideint 12345 4.99 -> 2473 183 | dvix152 divideint 12345 4.9 -> 2519 184 | dvix153 divideint 12345 5 -> 2469 185 | dvix154 divideint 12345 5.1 -> 2420 186 | dvix155 divideint 12345 5.01 -> 2464 187 | dvix156 divideint 12345 5.001 -> 2468 188 | dvix157 divideint 101 7.6 -> 13 189 | 190 | -- Various flavours of divideint by 0 191 | maxexponent: 999999999 192 | minexponent: -999999999 193 | dvix201 divideint 0 0 -> NaN Division_undefined 194 | dvix202 divideint 0.0E5 0 -> NaN Division_undefined 195 | dvix203 divideint 0.000 0 -> NaN Division_undefined 196 | dvix204 divideint 0.0001 0 -> Infinity Division_by_zero 197 | dvix205 divideint 0.01 0 -> Infinity Division_by_zero 198 | dvix206 divideint 0.1 0 -> Infinity Division_by_zero 199 | dvix207 divideint 1 0 -> Infinity Division_by_zero 200 | dvix208 divideint 1 0.0 -> Infinity Division_by_zero 201 | dvix209 divideint 10 0.0 -> Infinity Division_by_zero 202 | dvix210 divideint 1E+100 0.0 -> Infinity Division_by_zero 203 | dvix211 divideint 1E+1000 0 -> Infinity Division_by_zero 204 | dvix214 divideint -0.0001 0 -> -Infinity Division_by_zero 205 | dvix215 divideint -0.01 0 -> -Infinity Division_by_zero 206 | dvix216 divideint -0.1 0 -> -Infinity Division_by_zero 207 | dvix217 divideint -1 0 -> -Infinity Division_by_zero 208 | dvix218 divideint -1 0.0 -> -Infinity Division_by_zero 209 | dvix219 divideint -10 0.0 -> -Infinity Division_by_zero 210 | dvix220 divideint -1E+100 0.0 -> -Infinity Division_by_zero 211 | dvix221 divideint -1E+1000 0 -> -Infinity Division_by_zero 212 | 213 | -- test some cases that are close to exponent overflow 214 | maxexponent: 999999999 215 | minexponent: -999999999 216 | dvix270 divideint 1 1e999999999 -> 0 217 | dvix271 divideint 1 0.9e999999999 -> 0 218 | dvix272 divideint 1 0.99e999999999 -> 0 219 | dvix273 divideint 1 0.999999999e999999999 -> 0 220 | dvix274 divideint 9e999999999 1 -> NaN Division_impossible 221 | dvix275 divideint 9.9e999999999 1 -> NaN Division_impossible 222 | dvix276 divideint 9.99e999999999 1 -> NaN Division_impossible 223 | dvix277 divideint 9.99999999e999999999 1 -> NaN Division_impossible 224 | 225 | dvix280 divideint 0.1 9e-999999999 -> NaN Division_impossible 226 | dvix281 divideint 0.1 99e-999999999 -> NaN Division_impossible 227 | dvix282 divideint 0.1 999e-999999999 -> NaN Division_impossible 228 | 229 | dvix283 divideint 0.1 9e-999999998 -> NaN Division_impossible 230 | dvix284 divideint 0.1 99e-999999998 -> NaN Division_impossible 231 | dvix285 divideint 0.1 999e-999999998 -> NaN Division_impossible 232 | dvix286 divideint 0.1 999e-999999997 -> NaN Division_impossible 233 | dvix287 divideint 0.1 9999e-999999997 -> NaN Division_impossible 234 | dvix288 divideint 0.1 99999e-999999997 -> NaN Division_impossible 235 | 236 | -- GD edge cases: lhs smaller than rhs but more digits 237 | dvix301 divideint 0.9 2 -> 0 238 | dvix302 divideint 0.9 2.0 -> 0 239 | dvix303 divideint 0.9 2.1 -> 0 240 | dvix304 divideint 0.9 2.00 -> 0 241 | dvix305 divideint 0.9 2.01 -> 0 242 | dvix306 divideint 0.12 1 -> 0 243 | dvix307 divideint 0.12 1.0 -> 0 244 | dvix308 divideint 0.12 1.00 -> 0 245 | dvix309 divideint 0.12 1.0 -> 0 246 | dvix310 divideint 0.12 1.00 -> 0 247 | dvix311 divideint 0.12 2 -> 0 248 | dvix312 divideint 0.12 2.0 -> 0 249 | dvix313 divideint 0.12 2.1 -> 0 250 | dvix314 divideint 0.12 2.00 -> 0 251 | dvix315 divideint 0.12 2.01 -> 0 252 | 253 | -- overflow and underflow tests [from divide] 254 | maxexponent: 999999999 255 | minexponent: -999999999 256 | dvix330 divideint +1.23456789012345E-0 9E+999999999 -> 0 257 | dvix331 divideint 9E+999999999 +0.23456789012345E-0 -> NaN Division_impossible 258 | dvix332 divideint +0.100 9E+999999999 -> 0 259 | dvix333 divideint 9E-999999999 +9.100 -> 0 260 | dvix335 divideint -1.23456789012345E-0 9E+999999999 -> -0 261 | dvix336 divideint 9E+999999999 -0.83456789012345E-0 -> NaN Division_impossible 262 | dvix337 divideint -0.100 9E+999999999 -> -0 263 | dvix338 divideint 9E-999999999 -9.100 -> -0 264 | 265 | -- long operand checks 266 | maxexponent: 999 267 | minexponent: -999 268 | precision: 9 269 | dvix401 divideint 12345678000 100 -> 123456780 270 | dvix402 divideint 1 12345678000 -> 0 271 | dvix403 divideint 1234567800 10 -> 123456780 272 | dvix404 divideint 1 1234567800 -> 0 273 | dvix405 divideint 1234567890 10 -> 123456789 274 | dvix406 divideint 1 1234567890 -> 0 275 | dvix407 divideint 1234567891 10 -> 123456789 276 | dvix408 divideint 1 1234567891 -> 0 277 | dvix409 divideint 12345678901 100 -> 123456789 278 | dvix410 divideint 1 12345678901 -> 0 279 | dvix411 divideint 1234567896 10 -> 123456789 280 | dvix412 divideint 1 1234567896 -> 0 281 | dvix413 divideint 12345678948 100 -> 123456789 282 | dvix414 divideint 12345678949 100 -> 123456789 283 | dvix415 divideint 12345678950 100 -> 123456789 284 | dvix416 divideint 12345678951 100 -> 123456789 285 | dvix417 divideint 12345678999 100 -> 123456789 286 | 287 | precision: 15 288 | dvix441 divideint 12345678000 1 -> 12345678000 289 | dvix442 divideint 1 12345678000 -> 0 290 | dvix443 divideint 1234567800 1 -> 1234567800 291 | dvix444 divideint 1 1234567800 -> 0 292 | dvix445 divideint 1234567890 1 -> 1234567890 293 | dvix446 divideint 1 1234567890 -> 0 294 | dvix447 divideint 1234567891 1 -> 1234567891 295 | dvix448 divideint 1 1234567891 -> 0 296 | dvix449 divideint 12345678901 1 -> 12345678901 297 | dvix450 divideint 1 12345678901 -> 0 298 | dvix451 divideint 1234567896 1 -> 1234567896 299 | dvix452 divideint 1 1234567896 -> 0 300 | 301 | precision: 9 302 | rounding: half_up 303 | maxExponent: 999 304 | minexponent: -999 305 | 306 | -- more zeros, etc. 307 | dvix531 divideint 5.00 1E-3 -> 5000 308 | dvix532 divideint 00.00 0.000 -> NaN Division_undefined 309 | dvix533 divideint 00.00 0E-3 -> NaN Division_undefined 310 | dvix534 divideint 0 -0 -> NaN Division_undefined 311 | dvix535 divideint -0 0 -> NaN Division_undefined 312 | dvix536 divideint -0 -0 -> NaN Division_undefined 313 | 314 | dvix541 divideint 0 -1 -> -0 315 | dvix542 divideint -0 -1 -> 0 316 | dvix543 divideint 0 1 -> 0 317 | dvix544 divideint -0 1 -> -0 318 | dvix545 divideint -1 0 -> -Infinity Division_by_zero 319 | dvix546 divideint -1 -0 -> Infinity Division_by_zero 320 | dvix547 divideint 1 0 -> Infinity Division_by_zero 321 | dvix548 divideint 1 -0 -> -Infinity Division_by_zero 322 | 323 | dvix551 divideint 0.0 -1 -> -0 324 | dvix552 divideint -0.0 -1 -> 0 325 | dvix553 divideint 0.0 1 -> 0 326 | dvix554 divideint -0.0 1 -> -0 327 | dvix555 divideint -1.0 0 -> -Infinity Division_by_zero 328 | dvix556 divideint -1.0 -0 -> Infinity Division_by_zero 329 | dvix557 divideint 1.0 0 -> Infinity Division_by_zero 330 | dvix558 divideint 1.0 -0 -> -Infinity Division_by_zero 331 | 332 | dvix561 divideint 0 -1.0 -> -0 333 | dvix562 divideint -0 -1.0 -> 0 334 | dvix563 divideint 0 1.0 -> 0 335 | dvix564 divideint -0 1.0 -> -0 336 | dvix565 divideint -1 0.0 -> -Infinity Division_by_zero 337 | dvix566 divideint -1 -0.0 -> Infinity Division_by_zero 338 | dvix567 divideint 1 0.0 -> Infinity Division_by_zero 339 | dvix568 divideint 1 -0.0 -> -Infinity Division_by_zero 340 | 341 | dvix571 divideint 0.0 -1.0 -> -0 342 | dvix572 divideint -0.0 -1.0 -> 0 343 | dvix573 divideint 0.0 1.0 -> 0 344 | dvix574 divideint -0.0 1.0 -> -0 345 | dvix575 divideint -1.0 0.0 -> -Infinity Division_by_zero 346 | dvix576 divideint -1.0 -0.0 -> Infinity Division_by_zero 347 | dvix577 divideint 1.0 0.0 -> Infinity Division_by_zero 348 | dvix578 divideint 1.0 -0.0 -> -Infinity Division_by_zero 349 | 350 | -- Specials 351 | dvix580 divideint Inf -Inf -> NaN Invalid_operation 352 | dvix581 divideint Inf -1000 -> -Infinity 353 | dvix582 divideint Inf -1 -> -Infinity 354 | dvix583 divideint Inf -0 -> -Infinity 355 | dvix584 divideint Inf 0 -> Infinity 356 | dvix585 divideint Inf 1 -> Infinity 357 | dvix586 divideint Inf 1000 -> Infinity 358 | dvix587 divideint Inf Inf -> NaN Invalid_operation 359 | dvix588 divideint -1000 Inf -> -0 360 | dvix589 divideint -Inf Inf -> NaN Invalid_operation 361 | dvix590 divideint -1 Inf -> -0 362 | dvix591 divideint -0 Inf -> -0 363 | dvix592 divideint 0 Inf -> 0 364 | dvix593 divideint 1 Inf -> 0 365 | dvix594 divideint 1000 Inf -> 0 366 | dvix595 divideint Inf Inf -> NaN Invalid_operation 367 | 368 | dvix600 divideint -Inf -Inf -> NaN Invalid_operation 369 | dvix601 divideint -Inf -1000 -> Infinity 370 | dvix602 divideint -Inf -1 -> Infinity 371 | dvix603 divideint -Inf -0 -> Infinity 372 | dvix604 divideint -Inf 0 -> -Infinity 373 | dvix605 divideint -Inf 1 -> -Infinity 374 | dvix606 divideint -Inf 1000 -> -Infinity 375 | dvix607 divideint -Inf Inf -> NaN Invalid_operation 376 | dvix608 divideint -1000 Inf -> -0 377 | dvix609 divideint -Inf -Inf -> NaN Invalid_operation 378 | dvix610 divideint -1 -Inf -> 0 379 | dvix611 divideint -0 -Inf -> 0 380 | dvix612 divideint 0 -Inf -> -0 381 | dvix613 divideint 1 -Inf -> -0 382 | dvix614 divideint 1000 -Inf -> -0 383 | dvix615 divideint Inf -Inf -> NaN Invalid_operation 384 | 385 | dvix621 divideint NaN -Inf -> NaN 386 | dvix622 divideint NaN -1000 -> NaN 387 | dvix623 divideint NaN -1 -> NaN 388 | dvix624 divideint NaN -0 -> NaN 389 | dvix625 divideint NaN 0 -> NaN 390 | dvix626 divideint NaN 1 -> NaN 391 | dvix627 divideint NaN 1000 -> NaN 392 | dvix628 divideint NaN Inf -> NaN 393 | dvix629 divideint NaN NaN -> NaN 394 | dvix630 divideint -Inf NaN -> NaN 395 | dvix631 divideint -1000 NaN -> NaN 396 | dvix632 divideint -1 NaN -> NaN 397 | dvix633 divideint -0 NaN -> NaN 398 | dvix634 divideint 0 NaN -> NaN 399 | dvix635 divideint 1 NaN -> NaN 400 | dvix636 divideint 1000 NaN -> NaN 401 | dvix637 divideint Inf NaN -> NaN 402 | 403 | dvix641 divideint sNaN -Inf -> NaN Invalid_operation 404 | dvix642 divideint sNaN -1000 -> NaN Invalid_operation 405 | dvix643 divideint sNaN -1 -> NaN Invalid_operation 406 | dvix644 divideint sNaN -0 -> NaN Invalid_operation 407 | dvix645 divideint sNaN 0 -> NaN Invalid_operation 408 | dvix646 divideint sNaN 1 -> NaN Invalid_operation 409 | dvix647 divideint sNaN 1000 -> NaN Invalid_operation 410 | dvix648 divideint sNaN NaN -> NaN Invalid_operation 411 | dvix649 divideint sNaN sNaN -> NaN Invalid_operation 412 | dvix650 divideint NaN sNaN -> NaN Invalid_operation 413 | dvix651 divideint -Inf sNaN -> NaN Invalid_operation 414 | dvix652 divideint -1000 sNaN -> NaN Invalid_operation 415 | dvix653 divideint -1 sNaN -> NaN Invalid_operation 416 | dvix654 divideint -0 sNaN -> NaN Invalid_operation 417 | dvix655 divideint 0 sNaN -> NaN Invalid_operation 418 | dvix656 divideint 1 sNaN -> NaN Invalid_operation 419 | dvix657 divideint 1000 sNaN -> NaN Invalid_operation 420 | dvix658 divideint Inf sNaN -> NaN Invalid_operation 421 | dvix659 divideint NaN sNaN -> NaN Invalid_operation 422 | 423 | -- propagating NaNs 424 | dvix661 divideint NaN9 -Inf -> NaN9 425 | dvix662 divideint NaN8 1000 -> NaN8 426 | dvix663 divideint NaN7 Inf -> NaN7 427 | dvix664 divideint -NaN6 NaN5 -> -NaN6 428 | dvix665 divideint -Inf NaN4 -> NaN4 429 | dvix666 divideint -1000 NaN3 -> NaN3 430 | dvix667 divideint Inf -NaN2 -> -NaN2 431 | 432 | dvix671 divideint -sNaN99 -Inf -> -NaN99 Invalid_operation 433 | dvix672 divideint sNaN98 -1 -> NaN98 Invalid_operation 434 | dvix673 divideint sNaN97 NaN -> NaN97 Invalid_operation 435 | dvix674 divideint sNaN96 sNaN94 -> NaN96 Invalid_operation 436 | dvix675 divideint NaN95 sNaN93 -> NaN93 Invalid_operation 437 | dvix676 divideint -Inf sNaN92 -> NaN92 Invalid_operation 438 | dvix677 divideint 0 sNaN91 -> NaN91 Invalid_operation 439 | dvix678 divideint Inf -sNaN90 -> -NaN90 Invalid_operation 440 | dvix679 divideint NaN sNaN89 -> NaN89 Invalid_operation 441 | 442 | -- some long operand cases again 443 | precision: 8 444 | dvix710 divideint 100000001 1 -> NaN Division_impossible 445 | dvix711 divideint 100000000.4 1 -> NaN Division_impossible 446 | dvix712 divideint 100000000.5 1 -> NaN Division_impossible 447 | dvix713 divideint 100000000.9 1 -> NaN Division_impossible 448 | dvix714 divideint 100000000.999 1 -> NaN Division_impossible 449 | precision: 6 450 | dvix720 divideint 100000000 1 -> NaN Division_impossible 451 | dvix721 divideint 10000000 1 -> NaN Division_impossible 452 | dvix722 divideint 1000000 1 -> NaN Division_impossible 453 | dvix723 divideint 100000 1 -> 100000 454 | dvix724 divideint 10000 1 -> 10000 455 | dvix725 divideint 1000 1 -> 1000 456 | dvix726 divideint 100 1 -> 100 457 | dvix727 divideint 10 1 -> 10 458 | dvix728 divideint 1 1 -> 1 459 | dvix729 divideint 1 10 -> 0 460 | 461 | precision: 9 462 | maxexponent: 999999999 463 | minexponent: -999999999 464 | dvix732 divideint 1 0.99e999999999 -> 0 465 | dvix733 divideint 1 0.999999999e999999999 -> 0 466 | dvix734 divideint 9e999999999 1 -> NaN Division_impossible 467 | dvix735 divideint 9.9e999999999 1 -> NaN Division_impossible 468 | dvix736 divideint 9.99e999999999 1 -> NaN Division_impossible 469 | dvix737 divideint 9.99999999e999999999 1 -> NaN Division_impossible 470 | 471 | dvix740 divideint 0.1 9e-999999999 -> NaN Division_impossible 472 | dvix741 divideint 0.1 99e-999999999 -> NaN Division_impossible 473 | dvix742 divideint 0.1 999e-999999999 -> NaN Division_impossible 474 | 475 | dvix743 divideint 0.1 9e-999999998 -> NaN Division_impossible 476 | dvix744 divideint 0.1 99e-999999998 -> NaN Division_impossible 477 | dvix745 divideint 0.1 999e-999999998 -> NaN Division_impossible 478 | dvix746 divideint 0.1 999e-999999997 -> NaN Division_impossible 479 | dvix747 divideint 0.1 9999e-999999997 -> NaN Division_impossible 480 | dvix748 divideint 0.1 99999e-999999997 -> NaN Division_impossible 481 | 482 | 483 | -- Null tests 484 | dvix900 divideint 10 # -> NaN Invalid_operation 485 | dvix901 divideint # 10 -> NaN Invalid_operation 486 | -------------------------------------------------------------------------------- /testdata/minus.decTest: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------ 2 | -- minus.decTest -- decimal negation -- 3 | -- Copyright (c) Mike Cowlishaw, 1981, 2010. All rights reserved. -- 4 | -- Parts copyright (c) IBM Corporation, 1981, 2008. -- 5 | ------------------------------------------------------------------------ 6 | -- Please see the document "General Decimal Arithmetic Testcases" -- 7 | -- at http://speleotrove.com/decimal for the description of -- 8 | -- these testcases. -- 9 | -- -- 10 | -- These testcases are experimental ('beta' versions), and they -- 11 | -- may contain errors. They are offered on an as-is basis. In -- 12 | -- particular, achieving the same results as the tests here is not -- 13 | -- a guarantee that an implementation complies with any Standard -- 14 | -- or specification. The tests are not exhaustive. -- 15 | -- -- 16 | -- Please send comments, suggestions, and corrections to the author: -- 17 | -- Mike Cowlishaw, mfc@speleotrove.com -- 18 | ------------------------------------------------------------------------ 19 | version: 2.62 20 | 21 | -- This set of tests primarily tests the existence of the operator. 22 | -- Subtraction, rounding, and more overflows are tested elsewhere. 23 | 24 | extended: 1 25 | precision: 9 26 | rounding: half_up 27 | maxExponent: 384 28 | minexponent: -383 29 | 30 | minx001 minus '1' -> '-1' 31 | minx002 minus '-1' -> '1' 32 | minx003 minus '1.00' -> '-1.00' 33 | minx004 minus '-1.00' -> '1.00' 34 | minx005 minus '0' -> '0' 35 | minx006 minus '0.00' -> '0.00' 36 | minx007 minus '00.0' -> '0.0' 37 | minx008 minus '00.00' -> '0.00' 38 | minx009 minus '00' -> '0' 39 | 40 | minx010 minus '-2' -> '2' 41 | minx011 minus '2' -> '-2' 42 | minx012 minus '-2.00' -> '2.00' 43 | minx013 minus '2.00' -> '-2.00' 44 | minx014 minus '-0' -> '0' 45 | minx015 minus '-0.00' -> '0.00' 46 | minx016 minus '-00.0' -> '0.0' 47 | minx017 minus '-00.00' -> '0.00' 48 | minx018 minus '-00' -> '0' 49 | 50 | -- "lhs" zeros in plus and minus have exponent = operand 51 | minx020 minus '-0E3' -> '0E+3' 52 | minx021 minus '-0E2' -> '0E+2' 53 | minx022 minus '-0E1' -> '0E+1' 54 | minx023 minus '-0E0' -> '0' 55 | minx024 minus '+0E0' -> '0' 56 | minx025 minus '+0E1' -> '0E+1' 57 | minx026 minus '+0E2' -> '0E+2' 58 | minx027 minus '+0E3' -> '0E+3' 59 | 60 | minx030 minus '-5E3' -> '5E+3' 61 | minx031 minus '-5E8' -> '5E+8' 62 | minx032 minus '-5E13' -> '5E+13' 63 | minx033 minus '-5E18' -> '5E+18' 64 | minx034 minus '+5E3' -> '-5E+3' 65 | minx035 minus '+5E8' -> '-5E+8' 66 | minx036 minus '+5E13' -> '-5E+13' 67 | minx037 minus '+5E18' -> '-5E+18' 68 | 69 | minx050 minus '-2000000' -> '2000000' 70 | minx051 minus '2000000' -> '-2000000' 71 | precision: 7 72 | minx052 minus '-2000000' -> '2000000' 73 | minx053 minus '2000000' -> '-2000000' 74 | precision: 6 75 | minx054 minus '-2000000' -> '2.00000E+6' Rounded 76 | minx055 minus '2000000' -> '-2.00000E+6' Rounded 77 | precision: 3 78 | minx056 minus '-2000000' -> '2.00E+6' Rounded 79 | minx057 minus '2000000' -> '-2.00E+6' Rounded 80 | 81 | -- more fixed, potential LHS swaps/overlays if done by 0 subtract x 82 | precision: 9 83 | minx060 minus '56267E-10' -> '-0.0000056267' 84 | minx061 minus '56267E-5' -> '-0.56267' 85 | minx062 minus '56267E-2' -> '-562.67' 86 | minx063 minus '56267E-1' -> '-5626.7' 87 | minx065 minus '56267E-0' -> '-56267' 88 | minx066 minus '56267E+0' -> '-56267' 89 | minx067 minus '56267E+1' -> '-5.6267E+5' 90 | minx068 minus '56267E+2' -> '-5.6267E+6' 91 | minx069 minus '56267E+3' -> '-5.6267E+7' 92 | minx070 minus '56267E+4' -> '-5.6267E+8' 93 | minx071 minus '56267E+5' -> '-5.6267E+9' 94 | minx072 minus '56267E+6' -> '-5.6267E+10' 95 | minx080 minus '-56267E-10' -> '0.0000056267' 96 | minx081 minus '-56267E-5' -> '0.56267' 97 | minx082 minus '-56267E-2' -> '562.67' 98 | minx083 minus '-56267E-1' -> '5626.7' 99 | minx085 minus '-56267E-0' -> '56267' 100 | minx086 minus '-56267E+0' -> '56267' 101 | minx087 minus '-56267E+1' -> '5.6267E+5' 102 | minx088 minus '-56267E+2' -> '5.6267E+6' 103 | minx089 minus '-56267E+3' -> '5.6267E+7' 104 | minx090 minus '-56267E+4' -> '5.6267E+8' 105 | minx091 minus '-56267E+5' -> '5.6267E+9' 106 | minx092 minus '-56267E+6' -> '5.6267E+10' 107 | 108 | 109 | -- overflow tests 110 | maxexponent: 999999999 111 | minexponent: -999999999 112 | precision: 3 113 | minx100 minus 9.999E+999999999 -> -Infinity Inexact Overflow Rounded 114 | minx101 minus -9.999E+999999999 -> Infinity Inexact Overflow Rounded 115 | 116 | -- subnormals and underflow 117 | precision: 3 118 | maxexponent: 999 119 | minexponent: -999 120 | minx110 minus 1.00E-999 -> -1.00E-999 121 | minx111 minus 0.1E-999 -> -1E-1000 Subnormal 122 | minx112 minus 0.10E-999 -> -1.0E-1000 Subnormal 123 | minx113 minus 0.100E-999 -> -1.0E-1000 Subnormal Rounded 124 | minx114 minus 0.01E-999 -> -1E-1001 Subnormal 125 | -- next is rounded to Emin 126 | minx115 minus 0.999E-999 -> -1.00E-999 Inexact Rounded Subnormal Underflow 127 | minx116 minus 0.099E-999 -> -1.0E-1000 Inexact Rounded Subnormal Underflow 128 | minx117 minus 0.009E-999 -> -1E-1001 Inexact Rounded Subnormal Underflow 129 | minx118 minus 0.001E-999 -> -0E-1001 Inexact Rounded Subnormal Underflow Clamped 130 | minx119 minus 0.0009E-999 -> -0E-1001 Inexact Rounded Subnormal Underflow Clamped 131 | minx120 minus 0.0001E-999 -> -0E-1001 Inexact Rounded Subnormal Underflow Clamped 132 | 133 | minx130 minus -1.00E-999 -> 1.00E-999 134 | minx131 minus -0.1E-999 -> 1E-1000 Subnormal 135 | minx132 minus -0.10E-999 -> 1.0E-1000 Subnormal 136 | minx133 minus -0.100E-999 -> 1.0E-1000 Subnormal Rounded 137 | minx134 minus -0.01E-999 -> 1E-1001 Subnormal 138 | -- next is rounded to Emin 139 | minx135 minus -0.999E-999 -> 1.00E-999 Inexact Rounded Subnormal Underflow 140 | minx136 minus -0.099E-999 -> 1.0E-1000 Inexact Rounded Subnormal Underflow 141 | minx137 minus -0.009E-999 -> 1E-1001 Inexact Rounded Subnormal Underflow 142 | minx138 minus -0.001E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 143 | minx139 minus -0.0009E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 144 | minx140 minus -0.0001E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 145 | 146 | 147 | -- long operand checks 148 | maxexponent: 999 149 | minexponent: -999 150 | precision: 9 151 | minx301 minus 12345678000 -> -1.23456780E+10 Rounded 152 | minx302 minus 1234567800 -> -1.23456780E+9 Rounded 153 | minx303 minus 1234567890 -> -1.23456789E+9 Rounded 154 | minx304 minus 1234567891 -> -1.23456789E+9 Inexact Rounded 155 | minx305 minus 12345678901 -> -1.23456789E+10 Inexact Rounded 156 | minx306 minus 1234567896 -> -1.23456790E+9 Inexact Rounded 157 | 158 | precision: 15 159 | -- still checking 160 | minx321 minus 12345678000 -> -12345678000 161 | minx322 minus 1234567800 -> -1234567800 162 | minx323 minus 1234567890 -> -1234567890 163 | minx324 minus 1234567891 -> -1234567891 164 | minx325 minus 12345678901 -> -12345678901 165 | minx326 minus 1234567896 -> -1234567896 166 | 167 | -- specials 168 | minx420 minus 'Inf' -> '-Infinity' 169 | minx421 minus '-Inf' -> 'Infinity' 170 | minx422 minus NaN -> NaN 171 | minx423 minus sNaN -> NaN Invalid_operation 172 | minx424 minus NaN255 -> NaN255 173 | minx425 minus sNaN256 -> NaN256 Invalid_operation 174 | minx426 minus -NaN -> -NaN 175 | minx427 minus -sNaN -> -NaN Invalid_operation 176 | minx428 minus -NaN255 -> -NaN255 177 | minx429 minus -sNaN256 -> -NaN256 Invalid_operation 178 | 179 | -- Null tests 180 | minx900 minus # -> NaN Invalid_operation 181 | 182 | -------------------------------------------------------------------------------- /testdata/plus.decTest: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------ 2 | -- plus.decTest -- decimal monadic addition -- 3 | -- Copyright (c) Mike Cowlishaw, 1981, 2010. All rights reserved. -- 4 | -- Parts copyright (c) IBM Corporation, 1981, 2008. -- 5 | ------------------------------------------------------------------------ 6 | -- Please see the document "General Decimal Arithmetic Testcases" -- 7 | -- at http://speleotrove.com/decimal for the description of -- 8 | -- these testcases. -- 9 | -- -- 10 | -- These testcases are experimental ('beta' versions), and they -- 11 | -- may contain errors. They are offered on an as-is basis. In -- 12 | -- particular, achieving the same results as the tests here is not -- 13 | -- a guarantee that an implementation complies with any Standard -- 14 | -- or specification. The tests are not exhaustive. -- 15 | -- -- 16 | -- Please send comments, suggestions, and corrections to the author: -- 17 | -- Mike Cowlishaw, mfc@speleotrove.com -- 18 | ------------------------------------------------------------------------ 19 | version: 2.62 20 | 21 | -- This set of tests primarily tests the existence of the operator. 22 | -- Addition and rounding, and most overflows, are tested elsewhere. 23 | 24 | extended: 1 25 | precision: 9 26 | rounding: half_up 27 | maxExponent: 384 28 | minexponent: -383 29 | 30 | plux001 plus '1' -> '1' 31 | plux002 plus '-1' -> '-1' 32 | plux003 plus '1.00' -> '1.00' 33 | plux004 plus '-1.00' -> '-1.00' 34 | plux005 plus '0' -> '0' 35 | plux006 plus '0.00' -> '0.00' 36 | plux007 plus '00.0' -> '0.0' 37 | plux008 plus '00.00' -> '0.00' 38 | plux009 plus '00' -> '0' 39 | 40 | plux010 plus '-2' -> '-2' 41 | plux011 plus '2' -> '2' 42 | plux012 plus '-2.00' -> '-2.00' 43 | plux013 plus '2.00' -> '2.00' 44 | plux014 plus '-0' -> '0' 45 | plux015 plus '-0.00' -> '0.00' 46 | plux016 plus '-00.0' -> '0.0' 47 | plux017 plus '-00.00' -> '0.00' 48 | plux018 plus '-00' -> '0' 49 | 50 | plux020 plus '-2000000' -> '-2000000' 51 | plux021 plus '2000000' -> '2000000' 52 | precision: 7 53 | plux022 plus '-2000000' -> '-2000000' 54 | plux023 plus '2000000' -> '2000000' 55 | precision: 6 56 | plux024 plus '-2000000' -> '-2.00000E+6' Rounded 57 | plux025 plus '2000000' -> '2.00000E+6' Rounded 58 | precision: 3 59 | plux026 plus '-2000000' -> '-2.00E+6' Rounded 60 | plux027 plus '2000000' -> '2.00E+6' Rounded 61 | 62 | -- more fixed, potential LHS swaps if done by add 0 63 | precision: 9 64 | plux060 plus '56267E-10' -> '0.0000056267' 65 | plux061 plus '56267E-5' -> '0.56267' 66 | plux062 plus '56267E-2' -> '562.67' 67 | plux063 plus '56267E-1' -> '5626.7' 68 | plux065 plus '56267E-0' -> '56267' 69 | plux066 plus '56267E+0' -> '56267' 70 | plux067 plus '56267E+1' -> '5.6267E+5' 71 | plux068 plus '56267E+2' -> '5.6267E+6' 72 | plux069 plus '56267E+3' -> '5.6267E+7' 73 | plux070 plus '56267E+4' -> '5.6267E+8' 74 | plux071 plus '56267E+5' -> '5.6267E+9' 75 | plux072 plus '56267E+6' -> '5.6267E+10' 76 | plux080 plus '-56267E-10' -> '-0.0000056267' 77 | plux081 plus '-56267E-5' -> '-0.56267' 78 | plux082 plus '-56267E-2' -> '-562.67' 79 | plux083 plus '-56267E-1' -> '-5626.7' 80 | plux085 plus '-56267E-0' -> '-56267' 81 | plux086 plus '-56267E+0' -> '-56267' 82 | plux087 plus '-56267E+1' -> '-5.6267E+5' 83 | plux088 plus '-56267E+2' -> '-5.6267E+6' 84 | plux089 plus '-56267E+3' -> '-5.6267E+7' 85 | plux090 plus '-56267E+4' -> '-5.6267E+8' 86 | plux091 plus '-56267E+5' -> '-5.6267E+9' 87 | plux092 plus '-56267E+6' -> '-5.6267E+10' 88 | 89 | -- "lhs" zeros in plus and minus have exponent = operand 90 | plux120 plus '-0E3' -> '0E+3' 91 | plux121 plus '-0E2' -> '0E+2' 92 | plux122 plus '-0E1' -> '0E+1' 93 | plux123 plus '-0E0' -> '0' 94 | plux124 plus '+0E0' -> '0' 95 | plux125 plus '+0E1' -> '0E+1' 96 | plux126 plus '+0E2' -> '0E+2' 97 | plux127 plus '+0E3' -> '0E+3' 98 | 99 | plux130 plus '-5E3' -> '-5E+3' 100 | plux131 plus '-5E8' -> '-5E+8' 101 | plux132 plus '-5E13' -> '-5E+13' 102 | plux133 plus '-5E18' -> '-5E+18' 103 | plux134 plus '+5E3' -> '5E+3' 104 | plux135 plus '+5E8' -> '5E+8' 105 | plux136 plus '+5E13' -> '5E+13' 106 | plux137 plus '+5E18' -> '5E+18' 107 | 108 | -- specials 109 | plux150 plus 'Inf' -> 'Infinity' 110 | plux151 plus '-Inf' -> '-Infinity' 111 | plux152 plus NaN -> NaN 112 | plux153 plus sNaN -> NaN Invalid_operation 113 | plux154 plus NaN77 -> NaN77 114 | plux155 plus sNaN88 -> NaN88 Invalid_operation 115 | plux156 plus -NaN -> -NaN 116 | plux157 plus -sNaN -> -NaN Invalid_operation 117 | plux158 plus -NaN77 -> -NaN77 118 | plux159 plus -sNaN88 -> -NaN88 Invalid_operation 119 | 120 | -- overflow tests 121 | maxexponent: 999999999 122 | minexponent: -999999999 123 | precision: 3 124 | plux160 plus 9.999E+999999999 -> Infinity Inexact Overflow Rounded 125 | plux161 plus -9.999E+999999999 -> -Infinity Inexact Overflow Rounded 126 | 127 | -- subnormals and underflow 128 | precision: 3 129 | maxexponent: 999 130 | minexponent: -999 131 | plux210 plus 1.00E-999 -> 1.00E-999 132 | plux211 plus 0.1E-999 -> 1E-1000 Subnormal 133 | plux212 plus 0.10E-999 -> 1.0E-1000 Subnormal 134 | plux213 plus 0.100E-999 -> 1.0E-1000 Subnormal Rounded 135 | plux214 plus 0.01E-999 -> 1E-1001 Subnormal 136 | -- next is rounded to Emin 137 | plux215 plus 0.999E-999 -> 1.00E-999 Inexact Rounded Subnormal Underflow 138 | plux216 plus 0.099E-999 -> 1.0E-1000 Inexact Rounded Subnormal Underflow 139 | plux217 plus 0.009E-999 -> 1E-1001 Inexact Rounded Subnormal Underflow 140 | plux218 plus 0.001E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 141 | plux219 plus 0.0009E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 142 | plux220 plus 0.0001E-999 -> 0E-1001 Inexact Rounded Subnormal Underflow Clamped 143 | 144 | plux230 plus -1.00E-999 -> -1.00E-999 145 | plux231 plus -0.1E-999 -> -1E-1000 Subnormal 146 | plux232 plus -0.10E-999 -> -1.0E-1000 Subnormal 147 | plux233 plus -0.100E-999 -> -1.0E-1000 Subnormal Rounded 148 | plux234 plus -0.01E-999 -> -1E-1001 Subnormal 149 | -- next is rounded to Emin 150 | plux235 plus -0.999E-999 -> -1.00E-999 Inexact Rounded Subnormal Underflow 151 | plux236 plus -0.099E-999 -> -1.0E-1000 Inexact Rounded Subnormal Underflow 152 | plux237 plus -0.009E-999 -> -1E-1001 Inexact Rounded Subnormal Underflow 153 | plux238 plus -0.001E-999 -> -0E-1001 Inexact Rounded Subnormal Underflow Clamped 154 | plux239 plus -0.0009E-999 -> -0E-1001 Inexact Rounded Subnormal Underflow Clamped 155 | plux240 plus -0.0001E-999 -> -0E-1001 Inexact Rounded Subnormal Underflow Clamped 156 | 157 | -- subnormals clamped to 0-Etiny 158 | precision: 16 159 | maxExponent: 384 160 | minExponent: -383 161 | plux251 plus 7E-398 -> 7E-398 Subnormal 162 | plux252 plus 0E-398 -> 0E-398 163 | plux253 plus 7E-399 -> 1E-398 Subnormal Underflow Inexact Rounded 164 | plux254 plus 4E-399 -> 0E-398 Clamped Subnormal Underflow Inexact Rounded 165 | plux255 plus 7E-400 -> 0E-398 Clamped Subnormal Underflow Inexact Rounded 166 | plux256 plus 7E-401 -> 0E-398 Clamped Subnormal Underflow Inexact Rounded 167 | plux257 plus 0E-399 -> 0E-398 Clamped 168 | plux258 plus 0E-400 -> 0E-398 Clamped 169 | plux259 plus 0E-401 -> 0E-398 Clamped 170 | 171 | -- long operand checks 172 | maxexponent: 999 173 | minexponent: -999 174 | precision: 9 175 | plux301 plus 12345678000 -> 1.23456780E+10 Rounded 176 | plux302 plus 1234567800 -> 1.23456780E+9 Rounded 177 | plux303 plus 1234567890 -> 1.23456789E+9 Rounded 178 | plux304 plus 1234567891 -> 1.23456789E+9 Inexact Rounded 179 | plux305 plus 12345678901 -> 1.23456789E+10 Inexact Rounded 180 | plux306 plus 1234567896 -> 1.23456790E+9 Inexact Rounded 181 | 182 | -- still checking 183 | precision: 15 184 | plux321 plus 12345678000 -> 12345678000 185 | plux322 plus 1234567800 -> 1234567800 186 | plux323 plus 1234567890 -> 1234567890 187 | plux324 plus 1234567891 -> 1234567891 188 | plux325 plus 12345678901 -> 12345678901 189 | plux326 plus 1234567896 -> 1234567896 190 | precision: 9 191 | 192 | -- Null tests 193 | plu900 plus # -> NaN Invalid_operation 194 | 195 | -------------------------------------------------------------------------------- /testdata/reduce.decTest: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------ 2 | -- reduce.decTest -- remove trailing zeros -- 3 | -- Copyright (c) Mike Cowlishaw, 1981, 2010. All rights reserved. -- 4 | -- Parts copyright (c) IBM Corporation, 1981, 2008. -- 5 | ------------------------------------------------------------------------ 6 | -- Please see the document "General Decimal Arithmetic Testcases" -- 7 | -- at http://speleotrove.com/decimal for the description of -- 8 | -- these testcases. -- 9 | -- -- 10 | -- These testcases are experimental ('beta' versions), and they -- 11 | -- may contain errors. They are offered on an as-is basis. In -- 12 | -- particular, achieving the same results as the tests here is not -- 13 | -- a guarantee that an implementation complies with any Standard -- 14 | -- or specification. The tests are not exhaustive. -- 15 | -- -- 16 | -- Please send comments, suggestions, and corrections to the author: -- 17 | -- Mike Cowlishaw, mfc@speleotrove.com -- 18 | ------------------------------------------------------------------------ 19 | 20 | version: 2.62 21 | 22 | extended: 1 23 | precision: 9 24 | rounding: half_up 25 | maxExponent: 999 26 | minexponent: -999 27 | 28 | redx001 reduce '1' -> '1' 29 | redx002 reduce '-1' -> '-1' 30 | redx003 reduce '1.00' -> '1' 31 | redx004 reduce '-1.00' -> '-1' 32 | redx005 reduce '0' -> '0' 33 | redx006 reduce '0.00' -> '0' 34 | redx007 reduce '00.0' -> '0' 35 | redx008 reduce '00.00' -> '0' 36 | redx009 reduce '00' -> '0' 37 | redx010 reduce '0E+1' -> '0' 38 | redx011 reduce '0E+5' -> '0' 39 | 40 | redx012 reduce '-2' -> '-2' 41 | redx013 reduce '2' -> '2' 42 | redx014 reduce '-2.00' -> '-2' 43 | redx015 reduce '2.00' -> '2' 44 | redx016 reduce '-0' -> '-0' 45 | redx017 reduce '-0.00' -> '-0' 46 | redx018 reduce '-00.0' -> '-0' 47 | redx019 reduce '-00.00' -> '-0' 48 | redx020 reduce '-00' -> '-0' 49 | redx021 reduce '-0E+5' -> '-0' 50 | redx022 reduce '-0E+1' -> '-0' 51 | 52 | redx030 reduce '+0.1' -> '0.1' 53 | redx031 reduce '-0.1' -> '-0.1' 54 | redx032 reduce '+0.01' -> '0.01' 55 | redx033 reduce '-0.01' -> '-0.01' 56 | redx034 reduce '+0.001' -> '0.001' 57 | redx035 reduce '-0.001' -> '-0.001' 58 | redx036 reduce '+0.000001' -> '0.000001' 59 | redx037 reduce '-0.000001' -> '-0.000001' 60 | redx038 reduce '+0.000000000001' -> '1E-12' 61 | redx039 reduce '-0.000000000001' -> '-1E-12' 62 | 63 | redx041 reduce 1.1 -> 1.1 64 | redx042 reduce 1.10 -> 1.1 65 | redx043 reduce 1.100 -> 1.1 66 | redx044 reduce 1.110 -> 1.11 67 | redx045 reduce -1.1 -> -1.1 68 | redx046 reduce -1.10 -> -1.1 69 | redx047 reduce -1.100 -> -1.1 70 | redx048 reduce -1.110 -> -1.11 71 | redx049 reduce 9.9 -> 9.9 72 | redx050 reduce 9.90 -> 9.9 73 | redx051 reduce 9.900 -> 9.9 74 | redx052 reduce 9.990 -> 9.99 75 | redx053 reduce -9.9 -> -9.9 76 | redx054 reduce -9.90 -> -9.9 77 | redx055 reduce -9.900 -> -9.9 78 | redx056 reduce -9.990 -> -9.99 79 | 80 | -- some trailing fractional zeros with zeros in units 81 | redx060 reduce 10.0 -> 1E+1 82 | redx061 reduce 10.00 -> 1E+1 83 | redx062 reduce 100.0 -> 1E+2 84 | redx063 reduce 100.00 -> 1E+2 85 | redx064 reduce 1.1000E+3 -> 1.1E+3 86 | redx065 reduce 1.10000E+3 -> 1.1E+3 87 | redx066 reduce -10.0 -> -1E+1 88 | redx067 reduce -10.00 -> -1E+1 89 | redx068 reduce -100.0 -> -1E+2 90 | redx069 reduce -100.00 -> -1E+2 91 | redx070 reduce -1.1000E+3 -> -1.1E+3 92 | redx071 reduce -1.10000E+3 -> -1.1E+3 93 | 94 | -- some insignificant trailing zeros with positive exponent 95 | redx080 reduce 10E+1 -> 1E+2 96 | redx081 reduce 100E+1 -> 1E+3 97 | redx082 reduce 1.0E+2 -> 1E+2 98 | redx083 reduce 1.0E+3 -> 1E+3 99 | redx084 reduce 1.1E+3 -> 1.1E+3 100 | redx085 reduce 1.00E+3 -> 1E+3 101 | redx086 reduce 1.10E+3 -> 1.1E+3 102 | redx087 reduce -10E+1 -> -1E+2 103 | redx088 reduce -100E+1 -> -1E+3 104 | redx089 reduce -1.0E+2 -> -1E+2 105 | redx090 reduce -1.0E+3 -> -1E+3 106 | redx091 reduce -1.1E+3 -> -1.1E+3 107 | redx092 reduce -1.00E+3 -> -1E+3 108 | redx093 reduce -1.10E+3 -> -1.1E+3 109 | 110 | -- some significant trailing zeros, were we to be trimming 111 | redx100 reduce 11 -> 11 112 | redx101 reduce 10 -> 1E+1 113 | redx102 reduce 10. -> 1E+1 114 | redx103 reduce 1.1E+1 -> 11 115 | redx104 reduce 1.0E+1 -> 1E+1 116 | redx105 reduce 1.10E+2 -> 1.1E+2 117 | redx106 reduce 1.00E+2 -> 1E+2 118 | redx107 reduce 1.100E+3 -> 1.1E+3 119 | redx108 reduce 1.000E+3 -> 1E+3 120 | redx109 reduce 1.000000E+6 -> 1E+6 121 | redx110 reduce -11 -> -11 122 | redx111 reduce -10 -> -1E+1 123 | redx112 reduce -10. -> -1E+1 124 | redx113 reduce -1.1E+1 -> -11 125 | redx114 reduce -1.0E+1 -> -1E+1 126 | redx115 reduce -1.10E+2 -> -1.1E+2 127 | redx116 reduce -1.00E+2 -> -1E+2 128 | redx117 reduce -1.100E+3 -> -1.1E+3 129 | redx118 reduce -1.000E+3 -> -1E+3 130 | redx119 reduce -1.00000E+5 -> -1E+5 131 | redx120 reduce -1.000000E+6 -> -1E+6 132 | redx121 reduce -10.00000E+6 -> -1E+7 133 | redx122 reduce -100.0000E+6 -> -1E+8 134 | redx123 reduce -1000.000E+6 -> -1E+9 135 | redx124 reduce -10000.00E+6 -> -1E+10 136 | redx125 reduce -100000.0E+6 -> -1E+11 137 | redx126 reduce -1000000.E+6 -> -1E+12 138 | 139 | -- examples from decArith 140 | redx140 reduce '2.1' -> '2.1' 141 | redx141 reduce '-2.0' -> '-2' 142 | redx142 reduce '1.200' -> '1.2' 143 | redx143 reduce '-120' -> '-1.2E+2' 144 | redx144 reduce '120.00' -> '1.2E+2' 145 | redx145 reduce '0.00' -> '0' 146 | 147 | -- overflow tests 148 | maxexponent: 999999999 149 | minexponent: -999999999 150 | precision: 3 151 | redx160 reduce 9.999E+999999999 -> Infinity Inexact Overflow Rounded 152 | redx161 reduce -9.999E+999999999 -> -Infinity Inexact Overflow Rounded 153 | 154 | -- subnormals and underflow 155 | precision: 3 156 | maxexponent: 999 157 | minexponent: -999 158 | redx210 reduce 1.00E-999 -> 1E-999 159 | redx211 reduce 0.1E-999 -> 1E-1000 Subnormal 160 | redx212 reduce 0.10E-999 -> 1E-1000 Subnormal 161 | redx213 reduce 0.100E-999 -> 1E-1000 Subnormal Rounded 162 | redx214 reduce 0.01E-999 -> 1E-1001 Subnormal 163 | -- next is rounded to Emin 164 | redx215 reduce 0.999E-999 -> 1E-999 Inexact Rounded Subnormal Underflow 165 | redx216 reduce 0.099E-999 -> 1E-1000 Inexact Rounded Subnormal Underflow 166 | redx217 reduce 0.009E-999 -> 1E-1001 Inexact Rounded Subnormal Underflow 167 | redx218 reduce 0.001E-999 -> 0 Inexact Rounded Subnormal Underflow Clamped 168 | redx219 reduce 0.0009E-999 -> 0 Inexact Rounded Subnormal Underflow Clamped 169 | redx220 reduce 0.0001E-999 -> 0 Inexact Rounded Subnormal Underflow Clamped 170 | 171 | redx230 reduce -1.00E-999 -> -1E-999 172 | redx231 reduce -0.1E-999 -> -1E-1000 Subnormal 173 | redx232 reduce -0.10E-999 -> -1E-1000 Subnormal 174 | redx233 reduce -0.100E-999 -> -1E-1000 Subnormal Rounded 175 | redx234 reduce -0.01E-999 -> -1E-1001 Subnormal 176 | -- next is rounded to Emin 177 | redx235 reduce -0.999E-999 -> -1E-999 Inexact Rounded Subnormal Underflow 178 | redx236 reduce -0.099E-999 -> -1E-1000 Inexact Rounded Subnormal Underflow 179 | redx237 reduce -0.009E-999 -> -1E-1001 Inexact Rounded Subnormal Underflow 180 | redx238 reduce -0.001E-999 -> -0 Inexact Rounded Subnormal Underflow Clamped 181 | redx239 reduce -0.0009E-999 -> -0 Inexact Rounded Subnormal Underflow Clamped 182 | redx240 reduce -0.0001E-999 -> -0 Inexact Rounded Subnormal Underflow Clamped 183 | 184 | -- more reshaping 185 | precision: 9 186 | redx260 reduce '56260E-10' -> '0.000005626' 187 | redx261 reduce '56260E-5' -> '0.5626' 188 | redx262 reduce '56260E-2' -> '562.6' 189 | redx263 reduce '56260E-1' -> '5626' 190 | redx265 reduce '56260E-0' -> '5.626E+4' 191 | redx266 reduce '56260E+0' -> '5.626E+4' 192 | redx267 reduce '56260E+1' -> '5.626E+5' 193 | redx268 reduce '56260E+2' -> '5.626E+6' 194 | redx269 reduce '56260E+3' -> '5.626E+7' 195 | redx270 reduce '56260E+4' -> '5.626E+8' 196 | redx271 reduce '56260E+5' -> '5.626E+9' 197 | redx272 reduce '56260E+6' -> '5.626E+10' 198 | redx280 reduce '-56260E-10' -> '-0.000005626' 199 | redx281 reduce '-56260E-5' -> '-0.5626' 200 | redx282 reduce '-56260E-2' -> '-562.6' 201 | redx283 reduce '-56260E-1' -> '-5626' 202 | redx285 reduce '-56260E-0' -> '-5.626E+4' 203 | redx286 reduce '-56260E+0' -> '-5.626E+4' 204 | redx287 reduce '-56260E+1' -> '-5.626E+5' 205 | redx288 reduce '-56260E+2' -> '-5.626E+6' 206 | redx289 reduce '-56260E+3' -> '-5.626E+7' 207 | redx290 reduce '-56260E+4' -> '-5.626E+8' 208 | redx291 reduce '-56260E+5' -> '-5.626E+9' 209 | redx292 reduce '-56260E+6' -> '-5.626E+10' 210 | 211 | -- FL test 212 | precision: 40 213 | redx295 reduce 9892345673.0123456780000000000 -> 9892345673.012345678 214 | 215 | -- specials 216 | redx820 reduce 'Inf' -> 'Infinity' 217 | redx821 reduce '-Inf' -> '-Infinity' 218 | redx822 reduce NaN -> NaN 219 | redx823 reduce sNaN -> NaN Invalid_operation 220 | redx824 reduce NaN101 -> NaN101 221 | redx825 reduce sNaN010 -> NaN10 Invalid_operation 222 | redx827 reduce -NaN -> -NaN 223 | redx828 reduce -sNaN -> -NaN Invalid_operation 224 | redx829 reduce -NaN101 -> -NaN101 225 | redx830 reduce -sNaN010 -> -NaN10 Invalid_operation 226 | 227 | -- payload decapitate 228 | precision: 5 229 | redx62100 reduce sNaN1234567890 -> NaN67890 Invalid_operation 230 | 231 | -- Null test 232 | redx900 reduce # -> NaN Invalid_operation 233 | -------------------------------------------------------------------------------- /testdata/tointegral.decTest: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------ 2 | -- tointegral.decTest -- round decimal to integral value -- 3 | -- Copyright (c) Mike Cowlishaw, 1981, 2010. All rights reserved. -- 4 | -- Parts copyright (c) IBM Corporation, 1981, 2008. -- 5 | ------------------------------------------------------------------------ 6 | -- Please see the document "General Decimal Arithmetic Testcases" -- 7 | -- at http://speleotrove.com/decimal for the description of -- 8 | -- these testcases. -- 9 | -- -- 10 | -- These testcases are experimental ('beta' versions), and they -- 11 | -- may contain errors. They are offered on an as-is basis. In -- 12 | -- particular, achieving the same results as the tests here is not -- 13 | -- a guarantee that an implementation complies with any Standard -- 14 | -- or specification. The tests are not exhaustive. -- 15 | -- -- 16 | -- Please send comments, suggestions, and corrections to the author: -- 17 | -- Mike Cowlishaw, mfc@speleotrove.com -- 18 | ------------------------------------------------------------------------ 19 | version: 2.62 20 | 21 | -- This set of tests tests the extended specification 'round-to-integral 22 | -- value' operation (from IEEE 854, later modified in 754r). 23 | -- All non-zero results are defined as being those from either copy or 24 | -- quantize, so those are assumed to have been tested. 25 | -- Note that 754r requires that Inexact not be set, and we similarly 26 | -- assume Rounded is not set. 27 | 28 | extended: 1 29 | precision: 9 30 | rounding: half_up 31 | maxExponent: 999 32 | minExponent: -999 33 | 34 | intx001 tointegral 0 -> 0 35 | intx002 tointegral 0.0 -> 0 36 | intx003 tointegral 0.1 -> 0 37 | intx004 tointegral 0.2 -> 0 38 | intx005 tointegral 0.3 -> 0 39 | intx006 tointegral 0.4 -> 0 40 | intx007 tointegral 0.5 -> 1 41 | intx008 tointegral 0.6 -> 1 42 | intx009 tointegral 0.7 -> 1 43 | intx010 tointegral 0.8 -> 1 44 | intx011 tointegral 0.9 -> 1 45 | intx012 tointegral 1 -> 1 46 | intx013 tointegral 1.0 -> 1 47 | intx014 tointegral 1.1 -> 1 48 | intx015 tointegral 1.2 -> 1 49 | intx016 tointegral 1.3 -> 1 50 | intx017 tointegral 1.4 -> 1 51 | intx018 tointegral 1.5 -> 2 52 | intx019 tointegral 1.6 -> 2 53 | intx020 tointegral 1.7 -> 2 54 | intx021 tointegral 1.8 -> 2 55 | intx022 tointegral 1.9 -> 2 56 | -- negatives 57 | intx031 tointegral -0 -> -0 58 | intx032 tointegral -0.0 -> -0 59 | intx033 tointegral -0.1 -> -0 60 | intx034 tointegral -0.2 -> -0 61 | intx035 tointegral -0.3 -> -0 62 | intx036 tointegral -0.4 -> -0 63 | intx037 tointegral -0.5 -> -1 64 | intx038 tointegral -0.6 -> -1 65 | intx039 tointegral -0.7 -> -1 66 | intx040 tointegral -0.8 -> -1 67 | intx041 tointegral -0.9 -> -1 68 | intx042 tointegral -1 -> -1 69 | intx043 tointegral -1.0 -> -1 70 | intx044 tointegral -1.1 -> -1 71 | intx045 tointegral -1.2 -> -1 72 | intx046 tointegral -1.3 -> -1 73 | intx047 tointegral -1.4 -> -1 74 | intx048 tointegral -1.5 -> -2 75 | intx049 tointegral -1.6 -> -2 76 | intx050 tointegral -1.7 -> -2 77 | intx051 tointegral -1.8 -> -2 78 | intx052 tointegral -1.9 -> -2 79 | -- next two would be NaN using quantize(x, 0) 80 | intx053 tointegral 10E+30 -> 1.0E+31 81 | intx054 tointegral -10E+30 -> -1.0E+31 82 | 83 | -- numbers around precision 84 | precision: 9 85 | intx060 tointegral '56267E-10' -> '0' 86 | intx061 tointegral '56267E-5' -> '1' 87 | intx062 tointegral '56267E-2' -> '563' 88 | intx063 tointegral '56267E-1' -> '5627' 89 | intx065 tointegral '56267E-0' -> '56267' 90 | intx066 tointegral '56267E+0' -> '56267' 91 | intx067 tointegral '56267E+1' -> '5.6267E+5' 92 | intx068 tointegral '56267E+2' -> '5.6267E+6' 93 | intx069 tointegral '56267E+3' -> '5.6267E+7' 94 | intx070 tointegral '56267E+4' -> '5.6267E+8' 95 | intx071 tointegral '56267E+5' -> '5.6267E+9' 96 | intx072 tointegral '56267E+6' -> '5.6267E+10' 97 | intx073 tointegral '1.23E+96' -> '1.23E+96' 98 | intx074 tointegral '1.23E+384' -> '1.23E+384' 99 | intx075 tointegral '1.23E+999' -> '1.23E+999' 100 | 101 | intx080 tointegral '-56267E-10' -> '-0' 102 | intx081 tointegral '-56267E-5' -> '-1' 103 | intx082 tointegral '-56267E-2' -> '-563' 104 | intx083 tointegral '-56267E-1' -> '-5627' 105 | intx085 tointegral '-56267E-0' -> '-56267' 106 | intx086 tointegral '-56267E+0' -> '-56267' 107 | intx087 tointegral '-56267E+1' -> '-5.6267E+5' 108 | intx088 tointegral '-56267E+2' -> '-5.6267E+6' 109 | intx089 tointegral '-56267E+3' -> '-5.6267E+7' 110 | intx090 tointegral '-56267E+4' -> '-5.6267E+8' 111 | intx091 tointegral '-56267E+5' -> '-5.6267E+9' 112 | intx092 tointegral '-56267E+6' -> '-5.6267E+10' 113 | intx093 tointegral '-1.23E+96' -> '-1.23E+96' 114 | intx094 tointegral '-1.23E+384' -> '-1.23E+384' 115 | intx095 tointegral '-1.23E+999' -> '-1.23E+999' 116 | 117 | -- subnormal inputs 118 | intx100 tointegral 1E-999 -> 0 119 | intx101 tointegral 0.1E-999 -> 0 120 | intx102 tointegral 0.01E-999 -> 0 121 | intx103 tointegral 0E-999 -> 0 122 | 123 | -- specials and zeros 124 | intx120 tointegral 'Inf' -> Infinity 125 | intx121 tointegral '-Inf' -> -Infinity 126 | intx122 tointegral NaN -> NaN 127 | intx123 tointegral sNaN -> NaN Invalid_operation 128 | intx124 tointegral 0 -> 0 129 | intx125 tointegral -0 -> -0 130 | intx126 tointegral 0.000 -> 0 131 | intx127 tointegral 0.00 -> 0 132 | intx128 tointegral 0.0 -> 0 133 | intx129 tointegral 0 -> 0 134 | intx130 tointegral 0E-3 -> 0 135 | intx131 tointegral 0E-2 -> 0 136 | intx132 tointegral 0E-1 -> 0 137 | intx133 tointegral 0E-0 -> 0 138 | intx134 tointegral 0E+1 -> 0E+1 139 | intx135 tointegral 0E+2 -> 0E+2 140 | intx136 tointegral 0E+3 -> 0E+3 141 | intx137 tointegral 0E+4 -> 0E+4 142 | intx138 tointegral 0E+5 -> 0E+5 143 | intx139 tointegral -0.000 -> -0 144 | intx140 tointegral -0.00 -> -0 145 | intx141 tointegral -0.0 -> -0 146 | intx142 tointegral -0 -> -0 147 | intx143 tointegral -0E-3 -> -0 148 | intx144 tointegral -0E-2 -> -0 149 | intx145 tointegral -0E-1 -> -0 150 | intx146 tointegral -0E-0 -> -0 151 | intx147 tointegral -0E+1 -> -0E+1 152 | intx148 tointegral -0E+2 -> -0E+2 153 | intx149 tointegral -0E+3 -> -0E+3 154 | intx150 tointegral -0E+4 -> -0E+4 155 | intx151 tointegral -0E+5 -> -0E+5 156 | -- propagating NaNs 157 | intx152 tointegral NaN808 -> NaN808 158 | intx153 tointegral sNaN080 -> NaN80 Invalid_operation 159 | intx154 tointegral -NaN808 -> -NaN808 160 | intx155 tointegral -sNaN080 -> -NaN80 Invalid_operation 161 | intx156 tointegral -NaN -> -NaN 162 | intx157 tointegral -sNaN -> -NaN Invalid_operation 163 | 164 | -- examples 165 | rounding: half_up 166 | precision: 9 167 | intx200 tointegral 2.1 -> 2 168 | intx201 tointegral 100 -> 100 169 | intx202 tointegral 100.0 -> 100 170 | intx203 tointegral 101.5 -> 102 171 | intx204 tointegral -101.5 -> -102 172 | intx205 tointegral 10E+5 -> 1.0E+6 173 | intx206 tointegral 7.89E+77 -> 7.89E+77 174 | intx207 tointegral -Inf -> -Infinity 175 | 176 | 177 | -- all rounding modes 178 | rounding: half_even 179 | 180 | intx210 tointegral 55.5 -> 56 181 | intx211 tointegral 56.5 -> 56 182 | intx212 tointegral 57.5 -> 58 183 | intx213 tointegral -55.5 -> -56 184 | intx214 tointegral -56.5 -> -56 185 | intx215 tointegral -57.5 -> -58 186 | 187 | rounding: half_up 188 | 189 | intx220 tointegral 55.5 -> 56 190 | intx221 tointegral 56.5 -> 57 191 | intx222 tointegral 57.5 -> 58 192 | intx223 tointegral -55.5 -> -56 193 | intx224 tointegral -56.5 -> -57 194 | intx225 tointegral -57.5 -> -58 195 | 196 | rounding: half_down 197 | 198 | intx230 tointegral 55.5 -> 55 199 | intx231 tointegral 56.5 -> 56 200 | intx232 tointegral 57.5 -> 57 201 | intx233 tointegral -55.5 -> -55 202 | intx234 tointegral -56.5 -> -56 203 | intx235 tointegral -57.5 -> -57 204 | 205 | rounding: up 206 | 207 | intx240 tointegral 55.3 -> 56 208 | intx241 tointegral 56.3 -> 57 209 | intx242 tointegral 57.3 -> 58 210 | intx243 tointegral -55.3 -> -56 211 | intx244 tointegral -56.3 -> -57 212 | intx245 tointegral -57.3 -> -58 213 | 214 | rounding: down 215 | 216 | intx250 tointegral 55.7 -> 55 217 | intx251 tointegral 56.7 -> 56 218 | intx252 tointegral 57.7 -> 57 219 | intx253 tointegral -55.7 -> -55 220 | intx254 tointegral -56.7 -> -56 221 | intx255 tointegral -57.7 -> -57 222 | 223 | rounding: ceiling 224 | 225 | intx260 tointegral 55.3 -> 56 226 | intx261 tointegral 56.3 -> 57 227 | intx262 tointegral 57.3 -> 58 228 | intx263 tointegral -55.3 -> -55 229 | intx264 tointegral -56.3 -> -56 230 | intx265 tointegral -57.3 -> -57 231 | 232 | rounding: floor 233 | 234 | intx270 tointegral 55.7 -> 55 235 | intx271 tointegral 56.7 -> 56 236 | intx272 tointegral 57.7 -> 57 237 | intx273 tointegral -55.7 -> -56 238 | intx274 tointegral -56.7 -> -57 239 | intx275 tointegral -57.7 -> -58 240 | 241 | -------------------------------------------------------------------------------- /testdata/tointegralx.decTest: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------ 2 | -- tointegralx.decTest -- round decimal to integral value, exact -- 3 | -- Copyright (c) Mike Cowlishaw, 1981, 2010. All rights reserved. -- 4 | -- Parts copyright (c) IBM Corporation, 1981, 2008. -- 5 | ------------------------------------------------------------------------ 6 | -- Please see the document "General Decimal Arithmetic Testcases" -- 7 | -- at http://speleotrove.com/decimal for the description of -- 8 | -- these testcases. -- 9 | -- -- 10 | -- These testcases are experimental ('beta' versions), and they -- 11 | -- may contain errors. They are offered on an as-is basis. In -- 12 | -- particular, achieving the same results as the tests here is not -- 13 | -- a guarantee that an implementation complies with any Standard -- 14 | -- or specification. The tests are not exhaustive. -- 15 | -- -- 16 | -- Please send comments, suggestions, and corrections to the author: -- 17 | -- Mike Cowlishaw, mfc@speleotrove.com -- 18 | ------------------------------------------------------------------------ 19 | version: 2.62 20 | 21 | -- This set of tests tests the extended specification 'round-to-integral 22 | -- value' operation (from IEEE 854, later modified in 754r). 23 | -- All non-zero results are defined as being those from either copy or 24 | -- quantize, so those are assumed to have been tested. 25 | 26 | -- This tests toIntegraExact, which may set Inexact 27 | 28 | extended: 1 29 | precision: 9 30 | rounding: half_up 31 | maxExponent: 999 32 | minExponent: -999 33 | 34 | intxx001 tointegralx 0 -> 0 35 | intxx002 tointegralx 0.0 -> 0 36 | intxx003 tointegralx 0.1 -> 0 Inexact Rounded 37 | intxx004 tointegralx 0.2 -> 0 Inexact Rounded 38 | intxx005 tointegralx 0.3 -> 0 Inexact Rounded 39 | intxx006 tointegralx 0.4 -> 0 Inexact Rounded 40 | intxx007 tointegralx 0.5 -> 1 Inexact Rounded 41 | intxx008 tointegralx 0.6 -> 1 Inexact Rounded 42 | intxx009 tointegralx 0.7 -> 1 Inexact Rounded 43 | intxx010 tointegralx 0.8 -> 1 Inexact Rounded 44 | intxx011 tointegralx 0.9 -> 1 Inexact Rounded 45 | intxx012 tointegralx 1 -> 1 46 | intxx013 tointegralx 1.0 -> 1 Rounded 47 | intxx014 tointegralx 1.1 -> 1 Inexact Rounded 48 | intxx015 tointegralx 1.2 -> 1 Inexact Rounded 49 | intxx016 tointegralx 1.3 -> 1 Inexact Rounded 50 | intxx017 tointegralx 1.4 -> 1 Inexact Rounded 51 | intxx018 tointegralx 1.5 -> 2 Inexact Rounded 52 | intxx019 tointegralx 1.6 -> 2 Inexact Rounded 53 | intxx020 tointegralx 1.7 -> 2 Inexact Rounded 54 | intxx021 tointegralx 1.8 -> 2 Inexact Rounded 55 | intxx022 tointegralx 1.9 -> 2 Inexact Rounded 56 | -- negatives 57 | intxx031 tointegralx -0 -> -0 58 | intxx032 tointegralx -0.0 -> -0 59 | intxx033 tointegralx -0.1 -> -0 Inexact Rounded 60 | intxx034 tointegralx -0.2 -> -0 Inexact Rounded 61 | intxx035 tointegralx -0.3 -> -0 Inexact Rounded 62 | intxx036 tointegralx -0.4 -> -0 Inexact Rounded 63 | intxx037 tointegralx -0.5 -> -1 Inexact Rounded 64 | intxx038 tointegralx -0.6 -> -1 Inexact Rounded 65 | intxx039 tointegralx -0.7 -> -1 Inexact Rounded 66 | intxx040 tointegralx -0.8 -> -1 Inexact Rounded 67 | intxx041 tointegralx -0.9 -> -1 Inexact Rounded 68 | intxx042 tointegralx -1 -> -1 69 | intxx043 tointegralx -1.0 -> -1 Rounded 70 | intxx044 tointegralx -1.1 -> -1 Inexact Rounded 71 | intxx045 tointegralx -1.2 -> -1 Inexact Rounded 72 | intxx046 tointegralx -1.3 -> -1 Inexact Rounded 73 | intxx047 tointegralx -1.4 -> -1 Inexact Rounded 74 | intxx048 tointegralx -1.5 -> -2 Inexact Rounded 75 | intxx049 tointegralx -1.6 -> -2 Inexact Rounded 76 | intxx050 tointegralx -1.7 -> -2 Inexact Rounded 77 | intxx051 tointegralx -1.8 -> -2 Inexact Rounded 78 | intxx052 tointegralx -1.9 -> -2 Inexact Rounded 79 | -- next two would be NaN using quantize(x, 0) 80 | intxx053 tointegralx 10E+30 -> 1.0E+31 81 | intxx054 tointegralx -10E+30 -> -1.0E+31 82 | 83 | -- numbers around precision 84 | precision: 9 85 | intxx060 tointegralx '56267E-10' -> '0' Inexact Rounded 86 | intxx061 tointegralx '56267E-5' -> '1' Inexact Rounded 87 | intxx062 tointegralx '56267E-2' -> '563' Inexact Rounded 88 | intxx063 tointegralx '56267E-1' -> '5627' Inexact Rounded 89 | intxx065 tointegralx '56267E-0' -> '56267' 90 | intxx066 tointegralx '56267E+0' -> '56267' 91 | intxx067 tointegralx '56267E+1' -> '5.6267E+5' 92 | intxx068 tointegralx '56267E+2' -> '5.6267E+6' 93 | intxx069 tointegralx '56267E+3' -> '5.6267E+7' 94 | intxx070 tointegralx '56267E+4' -> '5.6267E+8' 95 | intxx071 tointegralx '56267E+5' -> '5.6267E+9' 96 | intxx072 tointegralx '56267E+6' -> '5.6267E+10' 97 | intxx073 tointegralx '1.23E+96' -> '1.23E+96' 98 | intxx074 tointegralx '1.23E+384' -> '1.23E+384' 99 | intxx075 tointegralx '1.23E+999' -> '1.23E+999' 100 | 101 | intxx080 tointegralx '-56267E-10' -> '-0' Inexact Rounded 102 | intxx081 tointegralx '-56267E-5' -> '-1' Inexact Rounded 103 | intxx082 tointegralx '-56267E-2' -> '-563' Inexact Rounded 104 | intxx083 tointegralx '-56267E-1' -> '-5627' Inexact Rounded 105 | intxx085 tointegralx '-56267E-0' -> '-56267' 106 | intxx086 tointegralx '-56267E+0' -> '-56267' 107 | intxx087 tointegralx '-56267E+1' -> '-5.6267E+5' 108 | intxx088 tointegralx '-56267E+2' -> '-5.6267E+6' 109 | intxx089 tointegralx '-56267E+3' -> '-5.6267E+7' 110 | intxx090 tointegralx '-56267E+4' -> '-5.6267E+8' 111 | intxx091 tointegralx '-56267E+5' -> '-5.6267E+9' 112 | intxx092 tointegralx '-56267E+6' -> '-5.6267E+10' 113 | intxx093 tointegralx '-1.23E+96' -> '-1.23E+96' 114 | intxx094 tointegralx '-1.23E+384' -> '-1.23E+384' 115 | intxx095 tointegralx '-1.23E+999' -> '-1.23E+999' 116 | 117 | -- subnormal inputs 118 | intxx100 tointegralx 1E-999 -> 0 Inexact Rounded 119 | intxx101 tointegralx 0.1E-999 -> 0 Inexact Rounded 120 | intxx102 tointegralx 0.01E-999 -> 0 Inexact Rounded 121 | intxx103 tointegralx 0E-999 -> 0 122 | 123 | -- specials and zeros 124 | intxx120 tointegralx 'Inf' -> Infinity 125 | intxx121 tointegralx '-Inf' -> -Infinity 126 | intxx122 tointegralx NaN -> NaN 127 | intxx123 tointegralx sNaN -> NaN Invalid_operation 128 | intxx124 tointegralx 0 -> 0 129 | intxx125 tointegralx -0 -> -0 130 | intxx126 tointegralx 0.000 -> 0 131 | intxx127 tointegralx 0.00 -> 0 132 | intxx128 tointegralx 0.0 -> 0 133 | intxx129 tointegralx 0 -> 0 134 | intxx130 tointegralx 0E-3 -> 0 135 | intxx131 tointegralx 0E-2 -> 0 136 | intxx132 tointegralx 0E-1 -> 0 137 | intxx133 tointegralx 0E-0 -> 0 138 | intxx134 tointegralx 0E+1 -> 0E+1 139 | intxx135 tointegralx 0E+2 -> 0E+2 140 | intxx136 tointegralx 0E+3 -> 0E+3 141 | intxx137 tointegralx 0E+4 -> 0E+4 142 | intxx138 tointegralx 0E+5 -> 0E+5 143 | intxx139 tointegralx -0.000 -> -0 144 | intxx140 tointegralx -0.00 -> -0 145 | intxx141 tointegralx -0.0 -> -0 146 | intxx142 tointegralx -0 -> -0 147 | intxx143 tointegralx -0E-3 -> -0 148 | intxx144 tointegralx -0E-2 -> -0 149 | intxx145 tointegralx -0E-1 -> -0 150 | intxx146 tointegralx -0E-0 -> -0 151 | intxx147 tointegralx -0E+1 -> -0E+1 152 | intxx148 tointegralx -0E+2 -> -0E+2 153 | intxx149 tointegralx -0E+3 -> -0E+3 154 | intxx150 tointegralx -0E+4 -> -0E+4 155 | intxx151 tointegralx -0E+5 -> -0E+5 156 | -- propagating NaNs 157 | intxx152 tointegralx NaN808 -> NaN808 158 | intxx153 tointegralx sNaN080 -> NaN80 Invalid_operation 159 | intxx154 tointegralx -NaN808 -> -NaN808 160 | intxx155 tointegralx -sNaN080 -> -NaN80 Invalid_operation 161 | intxx156 tointegralx -NaN -> -NaN 162 | intxx157 tointegralx -sNaN -> -NaN Invalid_operation 163 | 164 | -- examples 165 | rounding: half_up 166 | precision: 9 167 | intxx200 tointegralx 2.1 -> 2 Inexact Rounded 168 | intxx201 tointegralx 100 -> 100 169 | intxx202 tointegralx 100.0 -> 100 Rounded 170 | intxx203 tointegralx 101.5 -> 102 Inexact Rounded 171 | intxx204 tointegralx -101.5 -> -102 Inexact Rounded 172 | intxx205 tointegralx 10E+5 -> 1.0E+6 173 | intxx206 tointegralx 7.89E+77 -> 7.89E+77 174 | intxx207 tointegralx -Inf -> -Infinity 175 | 176 | 177 | -- all rounding modes 178 | rounding: half_even 179 | 180 | intxx210 tointegralx 55.5 -> 56 Inexact Rounded 181 | intxx211 tointegralx 56.5 -> 56 Inexact Rounded 182 | intxx212 tointegralx 57.5 -> 58 Inexact Rounded 183 | intxx213 tointegralx -55.5 -> -56 Inexact Rounded 184 | intxx214 tointegralx -56.5 -> -56 Inexact Rounded 185 | intxx215 tointegralx -57.5 -> -58 Inexact Rounded 186 | 187 | rounding: half_up 188 | 189 | intxx220 tointegralx 55.5 -> 56 Inexact Rounded 190 | intxx221 tointegralx 56.5 -> 57 Inexact Rounded 191 | intxx222 tointegralx 57.5 -> 58 Inexact Rounded 192 | intxx223 tointegralx -55.5 -> -56 Inexact Rounded 193 | intxx224 tointegralx -56.5 -> -57 Inexact Rounded 194 | intxx225 tointegralx -57.5 -> -58 Inexact Rounded 195 | 196 | rounding: half_down 197 | 198 | intxx230 tointegralx 55.5 -> 55 Inexact Rounded 199 | intxx231 tointegralx 56.5 -> 56 Inexact Rounded 200 | intxx232 tointegralx 57.5 -> 57 Inexact Rounded 201 | intxx233 tointegralx -55.5 -> -55 Inexact Rounded 202 | intxx234 tointegralx -56.5 -> -56 Inexact Rounded 203 | intxx235 tointegralx -57.5 -> -57 Inexact Rounded 204 | 205 | rounding: up 206 | 207 | intxx240 tointegralx 55.3 -> 56 Inexact Rounded 208 | intxx241 tointegralx 56.3 -> 57 Inexact Rounded 209 | intxx242 tointegralx 57.3 -> 58 Inexact Rounded 210 | intxx243 tointegralx -55.3 -> -56 Inexact Rounded 211 | intxx244 tointegralx -56.3 -> -57 Inexact Rounded 212 | intxx245 tointegralx -57.3 -> -58 Inexact Rounded 213 | 214 | rounding: down 215 | 216 | intxx250 tointegralx 55.7 -> 55 Inexact Rounded 217 | intxx251 tointegralx 56.7 -> 56 Inexact Rounded 218 | intxx252 tointegralx 57.7 -> 57 Inexact Rounded 219 | intxx253 tointegralx -55.7 -> -55 Inexact Rounded 220 | intxx254 tointegralx -56.7 -> -56 Inexact Rounded 221 | intxx255 tointegralx -57.7 -> -57 Inexact Rounded 222 | 223 | rounding: ceiling 224 | 225 | intxx260 tointegralx 55.3 -> 56 Inexact Rounded 226 | intxx261 tointegralx 56.3 -> 57 Inexact Rounded 227 | intxx262 tointegralx 57.3 -> 58 Inexact Rounded 228 | intxx263 tointegralx -55.3 -> -55 Inexact Rounded 229 | intxx264 tointegralx -56.3 -> -56 Inexact Rounded 230 | intxx265 tointegralx -57.3 -> -57 Inexact Rounded 231 | 232 | rounding: floor 233 | 234 | intxx270 tointegralx 55.7 -> 55 Inexact Rounded 235 | intxx271 tointegralx 56.7 -> 56 Inexact Rounded 236 | intxx272 tointegralx 57.7 -> 57 Inexact Rounded 237 | intxx273 tointegralx -55.7 -> -56 Inexact Rounded 238 | intxx274 tointegralx -56.7 -> -57 Inexact Rounded 239 | intxx275 tointegralx -57.7 -> -58 Inexact Rounded 240 | 241 | -- Int and uInt32 edge values for testing conversions 242 | precision: 16 243 | intxx300 tointegralx -2147483646 -> -2147483646 244 | intxx301 tointegralx -2147483647 -> -2147483647 245 | intxx302 tointegralx -2147483648 -> -2147483648 246 | intxx303 tointegralx -2147483649 -> -2147483649 247 | intxx304 tointegralx 2147483646 -> 2147483646 248 | intxx305 tointegralx 2147483647 -> 2147483647 249 | intxx306 tointegralx 2147483648 -> 2147483648 250 | intxx307 tointegralx 2147483649 -> 2147483649 251 | intxx308 tointegralx 4294967294 -> 4294967294 252 | intxx309 tointegralx 4294967295 -> 4294967295 253 | intxx310 tointegralx 4294967296 -> 4294967296 254 | intxx311 tointegralx 4294967297 -> 4294967297 255 | --------------------------------------------------------------------------------