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 15package apd_test 16 17import ( 18 "fmt" 19 20 "github.com/cockroachdb/apd" 21) 22 23// ExampleOverflow demonstrates how to detect or error on overflow. 24func 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: d: 998, overflow: false, err: <nil> 40 // d: 999, overflow: false, err: <nil> 41 // d: Infinity, overflow: true, err: overflow 42} 43 44// ExampleInexact demonstrates how to detect inexact operations. 45func ExampleContext_inexact() { 46 d := apd.New(27, 0) 47 three := apd.New(3, 0) 48 c := apd.BaseContext.WithPrecision(5) 49 for { 50 res, err := c.Quo(d, d, three) 51 fmt.Printf("d: %7s, inexact: %5v, err: %v\n", d, res.Inexact(), err) 52 if err != nil { 53 return 54 } 55 if res.Inexact() { 56 return 57 } 58 } 59 // Output: d: 9, inexact: false, err: <nil> 60 // d: 3, inexact: false, err: <nil> 61 // d: 1, inexact: false, err: <nil> 62 // d: 0.33333, inexact: true, err: <nil> 63} 64 65func ExampleContext_Quantize() { 66 input, _, _ := apd.NewFromString("123.45") 67 output := new(apd.Decimal) 68 c := apd.BaseContext.WithPrecision(10) 69 for i := int32(-3); i <= 3; i++ { 70 res, _ := c.Quantize(output, input, i) 71 fmt.Printf("%2v: %s", i, output) 72 if res != 0 { 73 fmt.Printf(" (%s)", res) 74 } 75 fmt.Println() 76 } 77 // Output: -3: 123.450 78 // -2: 123.45 79 // -1: 123.5 (inexact, rounded) 80 // 0: 123 (inexact, rounded) 81 // 1: 1.2E+2 (inexact, rounded) 82 // 2: 1E+2 (inexact, rounded) 83 // 3: 0E+3 (inexact, rounded) 84} 85 86func ExampleErrDecimal() { 87 c := apd.BaseContext.WithPrecision(5) 88 ed := apd.MakeErrDecimal(c) 89 d := apd.New(10, 0) 90 fmt.Printf("%s, err: %v\n", d, ed.Err()) 91 ed.Add(d, d, apd.New(2, 1)) // add 20 92 fmt.Printf("%s, err: %v\n", d, ed.Err()) 93 ed.Quo(d, d, apd.New(0, 0)) // divide by zero 94 fmt.Printf("%s, err: %v\n", d, ed.Err()) 95 ed.Sub(d, d, apd.New(1, 0)) // attempt to subtract 1 96 // The subtraction doesn't occur and doesn't change the error. 97 fmt.Printf("%s, err: %v\n", d, ed.Err()) 98 // Output: 10, err: <nil> 99 // 30, err: <nil> 100 // Infinity, err: division by zero 101 // Infinity, err: division by zero 102} 103 104// ExampleRoundToIntegralExact demonstrates how to use RoundToIntegralExact to 105// check if a number is an integer or not. Note the variations between integer 106// (which allows zeros after the decimal point) and strict (which does not). See 107// the documentation on Inexact and Rounded. 108func ExampleContext_RoundToIntegralExact() { 109 inputs := []string{ 110 "123.4", 111 "123.0", 112 "123", 113 "12E1", 114 "120E-1", 115 "120E-2", 116 } 117 for _, input := range inputs { 118 d, _, _ := apd.NewFromString(input) 119 res, _ := apd.BaseContext.RoundToIntegralExact(d, d) 120 integer := !res.Inexact() 121 strict := !res.Rounded() 122 fmt.Printf("input: % 6s, output: %3s, integer: %5t, strict: %5t, res:", input, d, integer, strict) 123 if res != 0 { 124 fmt.Printf(" %s", res) 125 } 126 fmt.Println() 127 } 128 // Output: input: 123.4, output: 123, integer: false, strict: false, res: inexact, rounded 129 // input: 123.0, output: 123, integer: true, strict: false, res: rounded 130 // input: 123, output: 123, integer: true, strict: true, res: 131 // input: 12E1, output: 120, integer: true, strict: true, res: 132 // input: 120E-1, output: 12, integer: true, strict: false, res: rounded 133 // input: 120E-2, output: 1, integer: false, strict: false, res: inexact, rounded 134} 135