...

Source file src/github.com/cockroachdb/apd/v3/context.go

Documentation: github.com/cockroachdb/apd/v3

     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  	"math"
    21  )
    22  
    23  // Context maintains options for Decimal operations. It can safely be used
    24  // concurrently, but not modified concurrently. Arguments for any method
    25  // can safely be used as both result and operand.
    26  type Context struct {
    27  	// Precision is the number of places to round during rounding; this is
    28  	// effectively the total number of digits (before and after the decimal
    29  	// point).
    30  	Precision uint32
    31  	// MaxExponent specifies the largest effective exponent. The
    32  	// effective exponent is the value of the Decimal in scientific notation. That
    33  	// is, for 10e2, the effective exponent is 3 (1.0e3). Zero (0) is not a special
    34  	// value; it does not disable this check.
    35  	MaxExponent int32
    36  	// MinExponent is similar to MaxExponent, but for the smallest effective
    37  	// exponent.
    38  	MinExponent int32
    39  	// Traps are the conditions which will trigger an error result if the
    40  	// corresponding Flag condition occurred.
    41  	Traps Condition
    42  	// Rounding specifies the Rounder to use during rounding. RoundHalfUp is used if
    43  	// empty or not present in Roundings.
    44  	Rounding Rounder
    45  }
    46  
    47  const (
    48  	// DefaultTraps is the default trap set used by BaseContext.
    49  	DefaultTraps = SystemOverflow |
    50  		SystemUnderflow |
    51  		Overflow |
    52  		Underflow |
    53  		Subnormal |
    54  		DivisionUndefined |
    55  		DivisionByZero |
    56  		DivisionImpossible |
    57  		InvalidOperation
    58  
    59  	errZeroPrecisionStr = "Context may not have 0 Precision for this operation"
    60  )
    61  
    62  // BaseContext is a useful default Context. Should not be mutated.
    63  var BaseContext = Context{
    64  	// Disable rounding.
    65  	Precision: 0,
    66  	// MaxExponent and MinExponent are set to the packages's limits.
    67  	MaxExponent: MaxExponent,
    68  	MinExponent: MinExponent,
    69  	// Default error conditions.
    70  	Traps: DefaultTraps,
    71  }
    72  
    73  // WithPrecision returns a copy of c but with the specified precision.
    74  func (c *Context) WithPrecision(p uint32) *Context {
    75  	r := new(Context)
    76  	*r = *c
    77  	r.Precision = p
    78  	return r
    79  }
    80  
    81  // goError converts flags into an error based on c.Traps.
    82  //gcassert:inline
    83  func (c *Context) goError(flags Condition) (Condition, error) {
    84  	if flags == 0 {
    85  		return flags, nil
    86  	}
    87  	return flags.GoError(c.Traps)
    88  }
    89  
    90  // etiny returns the smallest value an Exponent can contain.
    91  func (c *Context) etiny() int32 {
    92  	return c.MinExponent - int32(c.Precision) + 1
    93  }
    94  
    95  // shouldSetAsNaN determines whether setAsNaN should be called, given
    96  // the provided values, where x is required and y is optional. It is
    97  // split from setAsNaN to permit inlining of this function.
    98  //gcassert:inline
    99  func (c *Context) shouldSetAsNaN(x, y *Decimal) bool {
   100  	return x.Form == NaNSignaling || x.Form == NaN ||
   101  		(y != nil && (y.Form == NaNSignaling || y.Form == NaN))
   102  }
   103  
   104  // setAsNaN sets d to the first NaNSignaling, or otherwise first NaN, of
   105  // x and y. x is required, y is optional. Expects one of the two inputs
   106  // to be NaN.
   107  func (c *Context) setAsNaN(d *Decimal, x, y *Decimal) (Condition, error) {
   108  	var nan *Decimal
   109  	// Per the method contract, NaNSignaling takes precedence over NaN.
   110  	if x.Form == NaNSignaling {
   111  		nan = x
   112  	} else if y != nil && y.Form == NaNSignaling {
   113  		nan = y
   114  	} else if x.Form == NaN {
   115  		nan = x
   116  	} else if y != nil && y.Form == NaN {
   117  		nan = y
   118  	} else {
   119  		return 0, errors.New("no NaN value found; was shouldSetAsNaN called?")
   120  	}
   121  	d.Set(nan)
   122  	var res Condition
   123  	if nan.Form == NaNSignaling {
   124  		res = InvalidOperation
   125  		d.Form = NaN
   126  	}
   127  	_, err := c.goError(res)
   128  	return res, err
   129  }
   130  
   131  func (c *Context) add(d, x, y *Decimal, subtract bool) (Condition, error) {
   132  	if c.shouldSetAsNaN(x, y) {
   133  		return c.setAsNaN(d, x, y)
   134  	}
   135  	xn := x.Negative
   136  	yn := y.Negative != subtract
   137  	if xi, yi := x.Form == Infinite, y.Form == Infinite; xi || yi {
   138  		if xi && yi && xn != yn {
   139  			d.Set(decimalNaN)
   140  			return c.goError(InvalidOperation)
   141  		} else if xi {
   142  			d.Set(x)
   143  		} else {
   144  			d.Set(decimalInfinity)
   145  			d.Negative = yn
   146  		}
   147  		return 0, nil
   148  	}
   149  	var tmp BigInt
   150  	a, b, s, err := upscale(x, y, &tmp)
   151  	if err != nil {
   152  		return 0, fmt.Errorf("add: %w", err)
   153  	}
   154  	d.Negative = xn
   155  	if xn == yn {
   156  		d.Coeff.Add(a, b)
   157  	} else {
   158  		d.Coeff.Sub(a, b)
   159  		switch d.Coeff.Sign() {
   160  		case -1:
   161  			d.Negative = !d.Negative
   162  			d.Coeff.Neg(&d.Coeff)
   163  		case 0:
   164  			d.Negative = c.Rounding == RoundFloor
   165  		}
   166  	}
   167  	d.Exponent = s
   168  	d.Form = Finite
   169  	res := c.round(d, d)
   170  	return c.goError(res)
   171  }
   172  
   173  // Add sets d to the sum x+y.
   174  func (c *Context) Add(d, x, y *Decimal) (Condition, error) {
   175  	return c.add(d, x, y, false)
   176  }
   177  
   178  // Sub sets d to the difference x-y.
   179  func (c *Context) Sub(d, x, y *Decimal) (Condition, error) {
   180  	return c.add(d, x, y, true)
   181  }
   182  
   183  // Abs sets d to |x| (the absolute value of x).
   184  func (c *Context) Abs(d, x *Decimal) (Condition, error) {
   185  	if c.shouldSetAsNaN(x, nil) {
   186  		return c.setAsNaN(d, x, nil)
   187  	}
   188  	d.Abs(x)
   189  	res := c.round(d, d)
   190  	return c.goError(res)
   191  }
   192  
   193  // Neg sets d to -x.
   194  func (c *Context) Neg(d, x *Decimal) (Condition, error) {
   195  	if c.shouldSetAsNaN(x, nil) {
   196  		return c.setAsNaN(d, x, nil)
   197  	}
   198  	d.Neg(x)
   199  	res := c.round(d, d)
   200  	return c.goError(res)
   201  }
   202  
   203  // Mul sets d to the product x*y.
   204  func (c *Context) Mul(d, x, y *Decimal) (Condition, error) {
   205  	if c.shouldSetAsNaN(x, y) {
   206  		return c.setAsNaN(d, x, y)
   207  	}
   208  	// The sign of the result is the exclusive or of the signs of the operands.
   209  	neg := x.Negative != y.Negative
   210  	if xi, yi := x.Form == Infinite, y.Form == Infinite; xi || yi {
   211  		if x.IsZero() || y.IsZero() {
   212  			d.Set(decimalNaN)
   213  			return c.goError(InvalidOperation)
   214  		}
   215  		d.Set(decimalInfinity)
   216  		d.Negative = neg
   217  		return 0, nil
   218  	}
   219  
   220  	d.Coeff.Mul(&x.Coeff, &y.Coeff)
   221  	d.Negative = neg
   222  	d.Form = Finite
   223  	res := d.setExponent(c, unknownNumDigits, 0, int64(x.Exponent), int64(y.Exponent))
   224  	res |= c.round(d, d)
   225  	return c.goError(res)
   226  }
   227  
   228  func (c *Context) quoSpecials(d, x, y *Decimal, canClamp bool) (bool, Condition, error) {
   229  	if c.shouldSetAsNaN(x, y) {
   230  		res, err := c.setAsNaN(d, x, y)
   231  		return true, res, err
   232  	}
   233  
   234  	// The sign of the result is the exclusive or of the signs of the operands.
   235  	neg := x.Negative != y.Negative
   236  	if xi, yi := x.Form == Infinite, y.Form == Infinite; xi || yi {
   237  		var res Condition
   238  		if xi && yi {
   239  			d.Set(decimalNaN)
   240  			res = InvalidOperation
   241  		} else if xi {
   242  			d.Set(decimalInfinity)
   243  			d.Negative = neg
   244  		} else {
   245  			d.SetInt64(0)
   246  			d.Negative = neg
   247  			if canClamp {
   248  				d.Exponent = c.etiny()
   249  				res = Clamped
   250  			}
   251  		}
   252  		res, err := c.goError(res)
   253  		return true, res, err
   254  	}
   255  
   256  	if y.IsZero() {
   257  		var res Condition
   258  		if x.IsZero() {
   259  			res |= DivisionUndefined
   260  			d.Set(decimalNaN)
   261  		} else {
   262  			res |= DivisionByZero
   263  			d.Set(decimalInfinity)
   264  			d.Negative = neg
   265  		}
   266  		res, err := c.goError(res)
   267  		return true, res, err
   268  	}
   269  
   270  	if c.Precision == 0 {
   271  		// 0 precision is disallowed because we compute the required number of digits
   272  		// during the 10**x calculation using the precision.
   273  		return true, 0, errors.New(errZeroPrecisionStr)
   274  	}
   275  
   276  	return false, 0, nil
   277  }
   278  
   279  // Quo sets d to the quotient x/y for y != 0. c.Precision must be > 0. If an
   280  // exact division is required, use a context with high precision and verify
   281  // it was exact by checking the Inexact flag on the return Condition.
   282  func (c *Context) Quo(d, x, y *Decimal) (Condition, error) {
   283  	if set, res, err := c.quoSpecials(d, x, y, true); set {
   284  		return res, err
   285  	}
   286  
   287  	// The sign of the result is the exclusive or of the signs of the operands.
   288  	neg := x.Negative != y.Negative
   289  
   290  	// Shift the resulting exponent by the difference between the dividend and
   291  	// the divisor's exponent after performing arithmetic on the coefficients.
   292  	shift := int64(x.Exponent - y.Exponent)
   293  
   294  	var res Condition
   295  	if x.IsZero() {
   296  		d.Set(decimalZero)
   297  		d.Negative = neg
   298  		res |= d.setExponent(c, unknownNumDigits, res, shift)
   299  		return c.goError(res)
   300  	}
   301  
   302  	var dividend, divisor BigInt
   303  	dividend.Abs(&x.Coeff)
   304  	divisor.Abs(&y.Coeff)
   305  
   306  	// The operand coefficients are adjusted so that the coefficient of the
   307  	// dividend is greater than or equal to the coefficient of the divisor and
   308  	// is also less than ten times the coefficient of the divisor. While doing
   309  	// so, keep track of how far the two have been adjusted.
   310  	ndDividend := NumDigits(&dividend)
   311  	ndDivisor := NumDigits(&divisor)
   312  	ndDiff := ndDividend - ndDivisor
   313  	var tmpE BigInt
   314  	if ndDiff < 0 {
   315  		// numDigits(dividend) < numDigits(divisor), multiply dividend by 10^diff.
   316  		dividend.Mul(&dividend, tableExp10(-ndDiff, &tmpE))
   317  	} else if ndDiff > 0 {
   318  		// numDigits(dividend) > numDigits(divisor), multiply divisor by 10^diff.
   319  		divisor.Mul(&divisor, tableExp10(ndDiff, &tmpE))
   320  	}
   321  	adjCoeffs := -ndDiff
   322  	if dividend.Cmp(&divisor) < 0 {
   323  		// dividend < divisor, multiply dividend by 10.
   324  		dividend.Mul(&dividend, bigTen)
   325  		adjCoeffs++
   326  	}
   327  
   328  	// In order to compute the decimal remainder part, add enough 0s to the
   329  	// numerator to accurately round with the given precision. -1 because the
   330  	// previous adjustment ensured that the dividend is already greater than or
   331  	// equal to the divisor, so the result will always be greater than or equal
   332  	// to 1.
   333  	adjExp10 := int64(c.Precision - 1)
   334  	dividend.Mul(&dividend, tableExp10(adjExp10, &tmpE))
   335  
   336  	// Perform the division.
   337  	var rem BigInt
   338  	d.Coeff.QuoRem(&dividend, &divisor, &rem)
   339  	d.Form = Finite
   340  	d.Negative = neg
   341  
   342  	// If there was a remainder, it is taken into account for rounding. To do
   343  	// so, we determine whether the remainder was more or less than half of the
   344  	// divisor and round accordingly.
   345  	nd := NumDigits(&d.Coeff)
   346  	if rem.Sign() != 0 {
   347  		// Use the adjusted exponent to determine if we are Subnormal.
   348  		// If so, don't round. This computation of adj and the check
   349  		// against MinExponent mirrors the logic in setExponent.
   350  		adj := shift + (-adjCoeffs) + (-adjExp10) + nd - 1
   351  		if adj >= int64(c.MinExponent) {
   352  			res |= Inexact | Rounded
   353  			rem.Mul(&rem, bigTwo)
   354  			half := rem.Cmp(&divisor)
   355  			if c.Rounding.ShouldAddOne(&d.Coeff, d.Negative, half) {
   356  				d.Coeff.Add(&d.Coeff, bigOne)
   357  				// The coefficient changed, so recompute num digits in
   358  				// setExponent.
   359  				nd = unknownNumDigits
   360  			}
   361  		}
   362  	}
   363  
   364  	res |= d.setExponent(c, nd, res, shift, -adjCoeffs, -adjExp10)
   365  	return c.goError(res)
   366  }
   367  
   368  // QuoInteger sets d to the integer part of the quotient x/y. If the result
   369  // cannot fit in d.Precision digits, an error is returned.
   370  func (c *Context) QuoInteger(d, x, y *Decimal) (Condition, error) {
   371  	if set, res, err := c.quoSpecials(d, x, y, false); set {
   372  		return res, err
   373  	}
   374  
   375  	// The sign of the result is the exclusive or of the signs of the operands.
   376  	neg := x.Negative != y.Negative
   377  	var res Condition
   378  
   379  	var tmp BigInt
   380  	a, b, _, err := upscale(x, y, &tmp)
   381  	if err != nil {
   382  		return 0, fmt.Errorf("QuoInteger: %w", err)
   383  	}
   384  	d.Coeff.Quo(a, b)
   385  	d.Form = Finite
   386  	if d.NumDigits() > int64(c.Precision) {
   387  		d.Set(decimalNaN)
   388  		res |= DivisionImpossible
   389  	}
   390  	d.Exponent = 0
   391  	d.Negative = neg
   392  	return c.goError(res)
   393  }
   394  
   395  // Rem sets d to the remainder part of the quotient x/y. If
   396  // the integer part cannot fit in d.Precision digits, an error is returned.
   397  func (c *Context) Rem(d, x, y *Decimal) (Condition, error) {
   398  	if c.shouldSetAsNaN(x, y) {
   399  		return c.setAsNaN(d, x, y)
   400  	}
   401  
   402  	if x.Form != Finite {
   403  		d.Set(decimalNaN)
   404  		return c.goError(InvalidOperation)
   405  	}
   406  	if y.Form == Infinite {
   407  		d.Set(x)
   408  		return 0, nil
   409  	}
   410  
   411  	var res Condition
   412  	if y.IsZero() {
   413  		if x.IsZero() {
   414  			res |= DivisionUndefined
   415  		} else {
   416  			res |= InvalidOperation
   417  		}
   418  		d.Set(decimalNaN)
   419  		return c.goError(res)
   420  	}
   421  	var tmp1 BigInt
   422  	a, b, s, err := upscale(x, y, &tmp1)
   423  	if err != nil {
   424  		return 0, fmt.Errorf("Rem: %w", err)
   425  	}
   426  	var tmp2 BigInt
   427  	tmp2.QuoRem(a, b, &d.Coeff)
   428  	if NumDigits(&tmp2) > int64(c.Precision) {
   429  		d.Set(decimalNaN)
   430  		return c.goError(DivisionImpossible)
   431  	}
   432  	d.Form = Finite
   433  	d.Exponent = s
   434  	// The sign of the result is sign if the dividend.
   435  	d.Negative = x.Negative
   436  	res |= c.round(d, d)
   437  	return c.goError(res)
   438  }
   439  
   440  func (c *Context) rootSpecials(d, x *Decimal, factor int32) (bool, Condition, error) {
   441  	if c.shouldSetAsNaN(x, nil) {
   442  		res, err := c.setAsNaN(d, x, nil)
   443  		return true, res, err
   444  	}
   445  	if x.Form == Infinite {
   446  		if x.Negative {
   447  			d.Set(decimalNaN)
   448  			res, err := c.goError(InvalidOperation)
   449  			return true, res, err
   450  		}
   451  		d.Set(decimalInfinity)
   452  		return true, 0, nil
   453  	}
   454  
   455  	switch x.Sign() {
   456  	case -1:
   457  		if factor%2 == 0 {
   458  			d.Set(decimalNaN)
   459  			res, err := c.goError(InvalidOperation)
   460  			return true, res, err
   461  		}
   462  	case 0:
   463  		d.Set(x)
   464  		d.Exponent /= factor
   465  		return true, 0, nil
   466  	}
   467  	return false, 0, nil
   468  }
   469  
   470  // Sqrt sets d to the square root of x. Sqrt uses the Babylonian method
   471  // for computing the square root, which uses O(log p) steps for p digits
   472  // of precision.
   473  func (c *Context) Sqrt(d, x *Decimal) (Condition, error) {
   474  	// See: Properly Rounded Variable Precision Square Root by T. E. Hull
   475  	// and A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3,
   476  	// pp229–237, ACM, September 1985.
   477  
   478  	if set, res, err := c.rootSpecials(d, x, 2); set {
   479  		return res, err
   480  	}
   481  
   482  	// workp is the number of digits of precision used. We use the same precision
   483  	// as in decNumber.
   484  	workp := c.Precision + 1
   485  	if nd := uint32(x.NumDigits()); workp < nd {
   486  		workp = nd
   487  	}
   488  	if workp < 7 {
   489  		workp = 7
   490  	}
   491  
   492  	var f Decimal
   493  	f.Set(x)
   494  	nd := x.NumDigits()
   495  	e := nd + int64(x.Exponent)
   496  	f.Exponent = int32(-nd)
   497  	nc := c.WithPrecision(workp)
   498  	nc.Rounding = RoundHalfEven
   499  	ed := MakeErrDecimal(nc)
   500  	// Set approx to the first guess, based on whether e (the exponent part of x)
   501  	// is odd or even.
   502  	var approx Decimal
   503  	if e%2 == 0 {
   504  		approx.SetFinite(819, -3)
   505  		ed.Mul(&approx, &approx, &f)
   506  		ed.Add(&approx, &approx, New(259, -3))
   507  	} else {
   508  		f.Exponent--
   509  		e++
   510  		approx.SetFinite(259, -2)
   511  		ed.Mul(&approx, &approx, &f)
   512  		ed.Add(&approx, &approx, New(819, -4))
   513  	}
   514  
   515  	// Now we repeatedly improve approx. Our precision improves quadratically,
   516  	// which we keep track of in p.
   517  	p := uint32(3)
   518  	var tmp Decimal
   519  
   520  	// The algorithm in the paper says to use c.Precision + 2. decNumber uses
   521  	// workp + 2. But we use workp + 5 to make the tests pass. This means it is
   522  	// possible there are inputs we don't compute correctly and could be 1ulp off.
   523  	for maxp := workp + 5; p != maxp; {
   524  		p = 2*p - 2
   525  		if p > maxp {
   526  			p = maxp
   527  		}
   528  		nc.Precision = p
   529  		// tmp = f / approx
   530  		ed.Quo(&tmp, &f, &approx)
   531  		// tmp = approx + f / approx
   532  		ed.Add(&tmp, &tmp, &approx)
   533  		// approx = 0.5 * (approx + f / approx)
   534  		ed.Mul(&approx, &tmp, decimalHalf)
   535  	}
   536  
   537  	// At this point the paper says: "approx is now within 1 ulp of the properly
   538  	// rounded square root off; to ensure proper rounding, compare squares of
   539  	// (approx - l/2 ulp) and (approx + l/2 ulp) with f." We originally implemented
   540  	// the proceeding algorithm from the paper. However none of the tests take
   541  	// any of the branches that modify approx. Our best guess as to why is that
   542  	// since we use workp + 5 instead of the + 2 as described in the paper,
   543  	// we are more accurate than this section needed to account for. Thus,
   544  	// we have removed the block from this implementation.
   545  
   546  	if err := ed.Err(); err != nil {
   547  		return 0, err
   548  	}
   549  
   550  	d.Set(&approx)
   551  	d.Exponent += int32(e / 2)
   552  	nc.Precision = c.Precision
   553  	nc.Rounding = RoundHalfEven
   554  	res := nc.round(d, d)
   555  	return nc.goError(res)
   556  }
   557  
   558  // Cbrt sets d to the cube root of x.
   559  func (c *Context) Cbrt(d, x *Decimal) (Condition, error) {
   560  	// The cube root calculation is implemented using Newton-Raphson
   561  	// method. We start with an initial estimate for cbrt(d), and
   562  	// then iterate:
   563  	//     x_{n+1} = 1/3 * ( 2 * x_n + (d / x_n / x_n) ).
   564  
   565  	if set, res, err := c.rootSpecials(d, x, 3); set {
   566  		return res, err
   567  	}
   568  
   569  	var ax, z Decimal
   570  	ax.Abs(x)
   571  	z.Set(&ax)
   572  	neg := x.Negative
   573  	nc := BaseContext.WithPrecision(c.Precision*2 + 2)
   574  	ed := MakeErrDecimal(nc)
   575  	exp8 := 0
   576  
   577  	// See: Turkowski, Ken. Computing the cube root. technical report, Apple
   578  	// Computer, 1998.
   579  	// https://people.freebsd.org/~lstewart/references/apple_tr_kt32_cuberoot.pdf
   580  	//
   581  	// Computing the cube root of any number is reduced to computing
   582  	// the cube root of a number between 0.125 and 1. After the next loops,
   583  	// x = z * 8^exp8 will hold.
   584  	for z.Cmp(decimalOneEighth) < 0 {
   585  		exp8--
   586  		ed.Mul(&z, &z, decimalEight)
   587  	}
   588  
   589  	for z.Cmp(decimalOne) > 0 {
   590  		exp8++
   591  		ed.Mul(&z, &z, decimalOneEighth)
   592  	}
   593  
   594  	// Use this polynomial to approximate the cube root between 0.125 and 1.
   595  	// z = (-0.46946116 * z + 1.072302) * z + 0.3812513
   596  	// It will serve as an initial estimate, hence the precision of this
   597  	// computation may only impact performance, not correctness.
   598  	var z0 Decimal
   599  	z0.Set(&z)
   600  	ed.Mul(&z, &z, decimalCbrtC1)
   601  	ed.Add(&z, &z, decimalCbrtC2)
   602  	ed.Mul(&z, &z, &z0)
   603  	ed.Add(&z, &z, decimalCbrtC3)
   604  
   605  	for ; exp8 < 0; exp8++ {
   606  		ed.Mul(&z, &z, decimalHalf)
   607  	}
   608  
   609  	for ; exp8 > 0; exp8-- {
   610  		ed.Mul(&z, &z, decimalTwo)
   611  	}
   612  
   613  	// Loop until convergence.
   614  	for loop := nc.newLoop("cbrt", &z, c.Precision+1, 1); ; {
   615  		// z = (2.0 * z0 +  x / (z0 * z0) ) / 3.0;
   616  		z0.Set(&z)
   617  		ed.Mul(&z, &z, &z0)
   618  		ed.Quo(&z, &ax, &z)
   619  		ed.Add(&z, &z, &z0)
   620  		ed.Add(&z, &z, &z0)
   621  		ed.Quo(&z, &z, decimalThree)
   622  
   623  		if err := ed.Err(); err != nil {
   624  			return 0, err
   625  		}
   626  		if done, err := loop.done(&z); err != nil {
   627  			return 0, err
   628  		} else if done {
   629  			break
   630  		}
   631  	}
   632  
   633  	z0.Set(x)
   634  	res := c.round(d, &z)
   635  	res, err := c.goError(res)
   636  	d.Negative = neg
   637  
   638  	// Set z = d^3 to check for exactness.
   639  	ed.Mul(&z, d, d)
   640  	ed.Mul(&z, &z, d)
   641  
   642  	if err := ed.Err(); err != nil {
   643  		return 0, err
   644  	}
   645  
   646  	// Result is exact
   647  	if z0.Cmp(&z) == 0 {
   648  		return 0, nil
   649  	}
   650  	return res, err
   651  }
   652  
   653  func (c *Context) logSpecials(d, x *Decimal) (bool, Condition, error) {
   654  	if c.shouldSetAsNaN(x, nil) {
   655  		res, err := c.setAsNaN(d, x, nil)
   656  		return true, res, err
   657  	}
   658  	if x.Sign() < 0 {
   659  		d.Set(decimalNaN)
   660  		res, err := c.goError(InvalidOperation)
   661  		return true, res, err
   662  	}
   663  	if x.Form == Infinite {
   664  		d.Set(decimalInfinity)
   665  		return true, 0, nil
   666  	}
   667  	if x.Cmp(decimalZero) == 0 {
   668  		d.Set(decimalInfinity)
   669  		d.Negative = true
   670  		return true, 0, nil
   671  	}
   672  	if x.Cmp(decimalOne) == 0 {
   673  		d.Set(decimalZero)
   674  		return true, 0, nil
   675  	}
   676  
   677  	return false, 0, nil
   678  }
   679  
   680  // Ln sets d to the natural log of x.
   681  func (c *Context) Ln(d, x *Decimal) (Condition, error) {
   682  	// See: On the Use of Iteration Methods for Approximating the Natural
   683  	// Logarithm, James F. Epperson, The American Mathematical Monthly, Vol. 96,
   684  	// No. 9, November 1989, pp. 831-835.
   685  
   686  	if set, res, err := c.logSpecials(d, x); set {
   687  		return res, err
   688  	}
   689  
   690  	// The internal precision needs to be a few digits higher because errors in
   691  	// series/iterations add up.
   692  	p := c.Precision + 2
   693  
   694  	nc := c.WithPrecision(p)
   695  	nc.Rounding = RoundHalfEven
   696  	ed := MakeErrDecimal(nc)
   697  
   698  	var tmp1, tmp2, tmp3, tmp4, z, resAdjust Decimal
   699  	z.Set(x)
   700  
   701  	// To get an initial estimate, we first reduce the input range to the interval
   702  	// [0.1, 1) by changing the exponent, and later adjust the result by a
   703  	// multiple of ln(10).
   704  	//
   705  	// However, this does not work well for z very close to 1, where the result is
   706  	// very close to 0. For example:
   707  	//   z     = 1.00001
   708  	//   ln(z) = 0.00000999995
   709  	// If we adjust by 10:
   710  	//   z'     = 0.100001
   711  	//   ln(z') = -2.30257509304
   712  	//   ln(10) =  2.30258509299
   713  	//   ln(z)  =  0.00001000...
   714  	//
   715  	// The issue is that we may need to calculate a much higher (~double)
   716  	// precision for ln(z) because many of the significant digits cancel out.
   717  	//
   718  	// Halley's iteration has a similar problem when z is close to 1: in this case
   719  	// the correction term (exp(a_n) - z) needs to be calculated to a high
   720  	// precision. So for z close to 1 (before scaling) we use a power series
   721  	// instead (which converges very rapidly in this range).
   722  
   723  	// tmp1 = z - 1
   724  	ed.Sub(&tmp1, &z, decimalOne)
   725  	// tmp3 = 0.1
   726  	tmp3.SetFinite(1, -1)
   727  
   728  	usePowerSeries := false
   729  
   730  	if tmp2.Abs(&tmp1).Cmp(&tmp3) <= 0 {
   731  		usePowerSeries = true
   732  	} else {
   733  		// Reduce input to range [0.1, 1).
   734  		expDelta := int32(z.NumDigits()) + z.Exponent
   735  		z.Exponent -= expDelta
   736  
   737  		// We multiplied the input by 10^-expDelta, we will need to add
   738  		//   ln(10^expDelta) = expDelta * ln(10)
   739  		// to the result.
   740  		resAdjust.setCoefficient(int64(expDelta))
   741  		ed.Mul(&resAdjust, &resAdjust, decimalLn10.get(p))
   742  
   743  		// tmp1 = z - 1
   744  		ed.Sub(&tmp1, &z, decimalOne)
   745  
   746  		if tmp2.Abs(&tmp1).Cmp(&tmp3) <= 0 {
   747  			usePowerSeries = true
   748  		} else {
   749  			// Compute an initial estimate using floats.
   750  			zFloat, err := z.Float64()
   751  			if err != nil {
   752  				// We know that z is in a reasonable range; no errors should happen during conversion.
   753  				return 0, err
   754  			}
   755  			if _, err := tmp1.SetFloat64(math.Log(zFloat)); err != nil {
   756  				return 0, err
   757  			}
   758  		}
   759  	}
   760  
   761  	if usePowerSeries {
   762  		// We use the power series:
   763  		//   ln(1+x) = 2 sum [ 1 / (2n+1) * (x / (x+2))^(2n+1) ]
   764  		//
   765  		// This converges rapidly for small x.
   766  		// See https://en.wikipedia.org/wiki/Logarithm#Power_series
   767  
   768  		// tmp1 is already x
   769  
   770  		// tmp3 = x + 2
   771  		ed.Add(&tmp3, &tmp1, decimalTwo)
   772  
   773  		// tmp2 = (x / (x+2))
   774  		ed.Quo(&tmp2, &tmp1, &tmp3)
   775  
   776  		// tmp1 = tmp3 = 2 * (x / (x+2))
   777  		ed.Add(&tmp3, &tmp2, &tmp2)
   778  		tmp1.Set(&tmp3)
   779  
   780  		var eps Decimal
   781  		eps.Coeff.Set(bigOne)
   782  		eps.Exponent = -int32(p)
   783  		for n := 1; ; n++ {
   784  
   785  			// tmp3 *= (x / (x+2))^2
   786  			ed.Mul(&tmp3, &tmp3, &tmp2)
   787  			ed.Mul(&tmp3, &tmp3, &tmp2)
   788  
   789  			// tmp4 = 2n+1
   790  			tmp4.SetFinite(int64(2*n+1), 0)
   791  
   792  			ed.Quo(&tmp4, &tmp3, &tmp4)
   793  
   794  			ed.Add(&tmp1, &tmp1, &tmp4)
   795  
   796  			if tmp4.Abs(&tmp4).Cmp(&eps) <= 0 {
   797  				break
   798  			}
   799  		}
   800  	} else {
   801  		// Use Halley's Iteration.
   802  		// We use a bit more precision than the context asks for in newLoop because
   803  		// this is not the final result.
   804  		for loop := nc.newLoop("ln", x, c.Precision+1, 1); ; {
   805  			// tmp1 = a_n (either from initial estimate or last iteration)
   806  
   807  			// tmp2 = exp(a_n)
   808  			ed.Exp(&tmp2, &tmp1)
   809  
   810  			// tmp3 = exp(a_n) - z
   811  			ed.Sub(&tmp3, &tmp2, &z)
   812  
   813  			// tmp3 = 2 * (exp(a_n) - z)
   814  			ed.Add(&tmp3, &tmp3, &tmp3)
   815  
   816  			// tmp4 = exp(a_n) + z
   817  			ed.Add(&tmp4, &tmp2, &z)
   818  
   819  			// tmp2 = 2 * (exp(a_n) - z) / (exp(a_n) + z)
   820  			ed.Quo(&tmp2, &tmp3, &tmp4)
   821  
   822  			// tmp1 = a_(n+1) = a_n - 2 * (exp(a_n) - z) / (exp(a_n) + z)
   823  			ed.Sub(&tmp1, &tmp1, &tmp2)
   824  
   825  			if done, err := loop.done(&tmp1); err != nil {
   826  				return 0, err
   827  			} else if done {
   828  				break
   829  			}
   830  			if err := ed.Err(); err != nil {
   831  				return 0, err
   832  			}
   833  		}
   834  	}
   835  
   836  	// Apply the adjustment due to the initial rescaling.
   837  	ed.Add(&tmp1, &tmp1, &resAdjust)
   838  
   839  	if err := ed.Err(); err != nil {
   840  		return 0, err
   841  	}
   842  	res := c.round(d, &tmp1)
   843  	res |= Inexact
   844  	return c.goError(res)
   845  }
   846  
   847  // Log10 sets d to the base 10 log of x.
   848  func (c *Context) Log10(d, x *Decimal) (Condition, error) {
   849  	if set, res, err := c.logSpecials(d, x); set {
   850  		return res, err
   851  	}
   852  
   853  	// TODO(mjibson): This is exact under some conditions.
   854  	res := Inexact
   855  
   856  	nc := BaseContext.WithPrecision(c.Precision + 2)
   857  	nc.Rounding = RoundHalfEven
   858  	var z Decimal
   859  	_, err := nc.Ln(&z, x)
   860  	if err != nil {
   861  		return 0, fmt.Errorf("ln: %w", err)
   862  	}
   863  	nc.Precision = c.Precision
   864  
   865  	qr, err := nc.Mul(d, &z, decimalInvLn10.get(c.Precision+2))
   866  	if err != nil {
   867  		return 0, err
   868  	}
   869  	res |= qr
   870  	return c.goError(res)
   871  }
   872  
   873  // Exp sets d = e**x.
   874  func (c *Context) Exp(d, x *Decimal) (Condition, error) {
   875  	// See: Variable Precision Exponential Function, T. E. Hull and A. Abrham, ACM
   876  	// Transactions on Mathematical Software, Vol 12 #2, pp79-91, ACM, June 1986.
   877  
   878  	if c.shouldSetAsNaN(x, nil) {
   879  		return c.setAsNaN(d, x, nil)
   880  	}
   881  	if x.Form == Infinite {
   882  		if x.Negative {
   883  			d.Set(decimalZero)
   884  		} else {
   885  			d.Set(decimalInfinity)
   886  		}
   887  		return 0, nil
   888  	}
   889  
   890  	if x.IsZero() {
   891  		d.Set(decimalOne)
   892  		return 0, nil
   893  	}
   894  
   895  	if c.Precision == 0 {
   896  		return 0, errors.New(errZeroPrecisionStr)
   897  	}
   898  
   899  	res := Inexact | Rounded
   900  
   901  	// Stage 1
   902  	cp := c.Precision
   903  	var tmp1 Decimal
   904  	tmp1.Abs(x)
   905  	if f, err := tmp1.Float64(); err == nil {
   906  		// This algorithm doesn't work if currentprecision*23 < |x|. Attempt to
   907  		// increase the working precision if needed as long as it isn't too large. If
   908  		// it is too large, don't bump the precision, causing an early overflow return.
   909  		if ncp := f / 23; ncp > float64(cp) && ncp < 1000 {
   910  			cp = uint32(math.Ceil(ncp))
   911  		}
   912  	}
   913  	var tmp2 Decimal
   914  	tmp2.SetInt64(int64(cp) * 23)
   915  	// if abs(x) > 23*currentprecision; assert false
   916  	if tmp1.Cmp(&tmp2) > 0 {
   917  		res |= Overflow
   918  		if x.Sign() < 0 {
   919  			res = res.negateOverflowFlags()
   920  			res |= Clamped
   921  			d.SetFinite(0, c.etiny())
   922  		} else {
   923  			d.Set(decimalInfinity)
   924  		}
   925  		return c.goError(res)
   926  	}
   927  	// if abs(x) <= setexp(.9, -currentprecision); then result 1
   928  	tmp2.SetFinite(9, int32(-cp)-1)
   929  	if tmp1.Cmp(&tmp2) <= 0 {
   930  		d.Set(decimalOne)
   931  		return c.goError(res)
   932  	}
   933  
   934  	// Stage 2
   935  	// Add x.NumDigits because the paper assumes that x.Coeff [0.1, 1).
   936  	t := x.Exponent + int32(x.NumDigits())
   937  	if t < 0 {
   938  		t = 0
   939  	}
   940  	var k, r Decimal
   941  	k.SetFinite(1, t)
   942  	nc := c.WithPrecision(cp)
   943  	nc.Rounding = RoundHalfEven
   944  	if _, err := nc.Quo(&r, x, &k); err != nil {
   945  		return 0, fmt.Errorf("Quo: %w", err)
   946  	}
   947  	var ra Decimal
   948  	ra.Abs(&r)
   949  	p := int64(cp) + int64(t) + 2
   950  
   951  	// Stage 3
   952  	rf, err := ra.Float64()
   953  	if err != nil {
   954  		return 0, fmt.Errorf("r.Float64: %w", err)
   955  	}
   956  	pf := float64(p)
   957  	nf := math.Ceil((1.435*pf - 1.182) / math.Log10(pf/rf))
   958  	if nf > 1000 || math.IsNaN(nf) {
   959  		return 0, errors.New("too many iterations")
   960  	}
   961  	n := int64(nf)
   962  
   963  	// Stage 4
   964  	nc.Precision = uint32(p)
   965  	ed := MakeErrDecimal(nc)
   966  	var sum Decimal
   967  	sum.SetInt64(1)
   968  	tmp2.Exponent = 0
   969  	for i := n - 1; i > 0; i-- {
   970  		tmp2.setCoefficient(i)
   971  		// tmp1 = r / i
   972  		ed.Quo(&tmp1, &r, &tmp2)
   973  		// sum = sum * r / i
   974  		ed.Mul(&sum, &tmp1, &sum)
   975  		// sum = sum + 1
   976  		ed.Add(&sum, &sum, decimalOne)
   977  	}
   978  	if err != ed.Err() {
   979  		return 0, err
   980  	}
   981  
   982  	// sum ** k
   983  	var tmpE BigInt
   984  	ki, err := exp10(int64(t), &tmpE)
   985  	if err != nil {
   986  		return 0, fmt.Errorf("ki: %w", err)
   987  	}
   988  	ires, err := nc.integerPower(d, &sum, ki)
   989  	if err != nil {
   990  		return 0, fmt.Errorf("integer power: %w", err)
   991  	}
   992  	res |= ires
   993  	nc.Precision = c.Precision
   994  	res |= nc.round(d, d)
   995  	return c.goError(res)
   996  }
   997  
   998  // integerPower sets d = x**y. d and x must not point to the same Decimal.
   999  func (c *Context) integerPower(d, x *Decimal, y *BigInt) (Condition, error) {
  1000  	// See: https://en.wikipedia.org/wiki/Exponentiation_by_squaring.
  1001  
  1002  	var b BigInt
  1003  	b.Set(y)
  1004  	neg := b.Sign() < 0
  1005  	if neg {
  1006  		b.Abs(&b)
  1007  	}
  1008  
  1009  	var n Decimal
  1010  	n.Set(x)
  1011  	z := d
  1012  	z.Set(decimalOne)
  1013  	ed := MakeErrDecimal(c)
  1014  	for b.Sign() > 0 {
  1015  		if b.Bit(0) == 1 {
  1016  			ed.Mul(z, z, &n)
  1017  		}
  1018  		b.Rsh(&b, 1)
  1019  
  1020  		// Only compute the next n if we are going to use it. Otherwise n can overflow
  1021  		// on the last iteration causing this to error.
  1022  		if b.Sign() > 0 {
  1023  			ed.Mul(&n, &n, &n)
  1024  		}
  1025  		if err := ed.Err(); err != nil {
  1026  			// In the negative case, convert overflow to underflow.
  1027  			if neg {
  1028  				ed.Flags = ed.Flags.negateOverflowFlags()
  1029  			}
  1030  			return ed.Flags, err
  1031  		}
  1032  	}
  1033  
  1034  	if neg {
  1035  		ed.Quo(z, decimalOne, z)
  1036  	}
  1037  	return ed.Flags, ed.Err()
  1038  }
  1039  
  1040  // Pow sets d = x**y.
  1041  func (c *Context) Pow(d, x, y *Decimal) (Condition, error) {
  1042  	if c.shouldSetAsNaN(x, y) {
  1043  		return c.setAsNaN(d, x, y)
  1044  	}
  1045  
  1046  	var integ, frac Decimal
  1047  	y.Modf(&integ, &frac)
  1048  	yIsInt := frac.IsZero()
  1049  	neg := x.Negative && y.Form == Finite && yIsInt && integ.Coeff.Bit(0) == 1 && integ.Exponent == 0
  1050  
  1051  	if x.Form == Infinite {
  1052  		var res Condition
  1053  		if y.Sign() == 0 {
  1054  			d.Set(decimalOne)
  1055  		} else if x.Negative && (y.Form == Infinite || !yIsInt) {
  1056  			d.Set(decimalNaN)
  1057  			res = InvalidOperation
  1058  		} else if y.Negative {
  1059  			d.Set(decimalZero)
  1060  		} else {
  1061  			d.Set(decimalInfinity)
  1062  		}
  1063  		d.Negative = neg
  1064  		return c.goError(res)
  1065  	}
  1066  
  1067  	// Check if y is of type int.
  1068  	var tmp Decimal
  1069  	tmp.Abs(y)
  1070  
  1071  	xs := x.Sign()
  1072  	ys := y.Sign()
  1073  
  1074  	if xs == 0 {
  1075  		var res Condition
  1076  		switch ys {
  1077  		case 0:
  1078  			d.Set(decimalNaN)
  1079  			res = InvalidOperation
  1080  		case 1:
  1081  			d.Set(decimalZero)
  1082  		default: // -1
  1083  			d.Set(decimalInfinity)
  1084  		}
  1085  		d.Negative = neg
  1086  		return c.goError(res)
  1087  	}
  1088  	if ys == 0 {
  1089  		d.Set(decimalOne)
  1090  		return 0, nil
  1091  	}
  1092  
  1093  	if xs < 0 && !yIsInt {
  1094  		d.Set(decimalNaN)
  1095  		return c.goError(InvalidOperation)
  1096  	}
  1097  
  1098  	// decNumber sets the precision to be max(x digits, c.Precision) +
  1099  	// len(exponent) + 4. 6 is used as the exponent maximum length.
  1100  	p := c.Precision
  1101  	if nd := uint32(x.NumDigits()); p < nd {
  1102  		p = nd
  1103  	}
  1104  	p += 4 + 6
  1105  
  1106  	nc := BaseContext.WithPrecision(p)
  1107  
  1108  	z := d
  1109  	if z == x {
  1110  		z = new(Decimal)
  1111  	}
  1112  
  1113  	// If integ.Exponent > 0, we need to add trailing 0s to integ.Coeff.
  1114  	res := c.quantize(&integ, &integ, 0)
  1115  	nres, err := nc.integerPower(z, x, integ.setBig(&integ.Coeff))
  1116  	res |= nres
  1117  	if err != nil {
  1118  		d.Set(decimalNaN)
  1119  		return res, err
  1120  	}
  1121  
  1122  	if yIsInt {
  1123  		res |= c.round(d, z)
  1124  		return c.goError(res)
  1125  	}
  1126  
  1127  	ed := MakeErrDecimal(nc)
  1128  
  1129  	// Compute x**frac(y)
  1130  	ed.Abs(&tmp, x)
  1131  	ed.Ln(&tmp, &tmp)
  1132  	ed.Mul(&tmp, &tmp, &frac)
  1133  	ed.Exp(&tmp, &tmp)
  1134  
  1135  	// Join integer and frac parts back.
  1136  	ed.Mul(&tmp, z, &tmp)
  1137  
  1138  	if err := ed.Err(); err != nil {
  1139  		return ed.Flags, err
  1140  	}
  1141  	res |= c.round(d, &tmp)
  1142  	d.Negative = neg
  1143  	res |= Inexact
  1144  	return c.goError(res)
  1145  }
  1146  
  1147  // Quantize adjusts and rounds x as necessary so it is represented with
  1148  // exponent exp and stores the result in d.
  1149  func (c *Context) Quantize(d, x *Decimal, exp int32) (Condition, error) {
  1150  	if c.shouldSetAsNaN(x, nil) {
  1151  		return c.setAsNaN(d, x, nil)
  1152  	}
  1153  	if x.Form == Infinite || exp < c.etiny() {
  1154  		d.Set(decimalNaN)
  1155  		return c.goError(InvalidOperation)
  1156  	}
  1157  	res := c.quantize(d, x, exp)
  1158  	if nd := d.NumDigits(); nd > int64(c.Precision) || exp > c.MaxExponent {
  1159  		res = InvalidOperation
  1160  		d.Set(decimalNaN)
  1161  	} else {
  1162  		res |= c.round(d, d)
  1163  		if res.Overflow() || res.Underflow() {
  1164  			res = InvalidOperation
  1165  			d.Set(decimalNaN)
  1166  		}
  1167  	}
  1168  	return c.goError(res)
  1169  }
  1170  
  1171  func (c *Context) quantize(d, v *Decimal, exp int32) Condition {
  1172  	diff := exp - v.Exponent
  1173  	d.Set(v)
  1174  	var res Condition
  1175  	if diff < 0 {
  1176  		if diff < MinExponent {
  1177  			return SystemUnderflow | Underflow
  1178  		}
  1179  		var tmpE BigInt
  1180  		d.Coeff.Mul(&d.Coeff, tableExp10(-int64(diff), &tmpE))
  1181  	} else if diff > 0 {
  1182  		p := int32(d.NumDigits()) - diff
  1183  		if p < 0 {
  1184  			if !d.IsZero() {
  1185  				d.Coeff.SetInt64(0)
  1186  				res = Inexact | Rounded
  1187  			}
  1188  		} else {
  1189  			nc := c.WithPrecision(uint32(p))
  1190  
  1191  			// The idea here is that the resulting d.Exponent after rounding will be 0. We
  1192  			// have a number of, say, 5 digits, but p (our precision) above is set at, say,
  1193  			// 3. So here d.Exponent is set to `-2`. We have a number like `NNN.xx`, where
  1194  			// the `.xx` part will be rounded away. However during rounding of 0.9 to 1.0,
  1195  			// d.Exponent could be set to 1 instead of 0, so we have to reduce it and
  1196  			// increase the coefficient below.
  1197  
  1198  			// Another solution is to set d.Exponent = v.Exponent and adjust it to exp,
  1199  			// instead of setting d.Exponent = -diff and adjusting it to zero. Although
  1200  			// this computes the correct result, it fails the Max/MinExponent checks
  1201  			// during Round and raises underflow flags. Quantize (as per the spec)
  1202  			// is guaranteed to not raise underflow, and using 0 instead of exp as the
  1203  			// target eliminates this problem.
  1204  
  1205  			d.Exponent = -diff
  1206  			// Round even if nc.Precision == 0.
  1207  			res = nc.Rounding.Round(nc, d, d, false /* disableIfPrecisionZero */)
  1208  			// Adjust for 0.9 -> 1.0 rollover.
  1209  			if d.Exponent > 0 {
  1210  				d.Coeff.Mul(&d.Coeff, bigTen)
  1211  			}
  1212  		}
  1213  	}
  1214  	d.Exponent = exp
  1215  	return res
  1216  }
  1217  
  1218  func (c *Context) toIntegral(d, x *Decimal) Condition {
  1219  	res := c.quantize(d, x, 0)
  1220  	return res
  1221  }
  1222  
  1223  func (c *Context) toIntegralSpecials(d, x *Decimal) (bool, Condition, error) {
  1224  	if c.shouldSetAsNaN(x, nil) {
  1225  		res, err := c.setAsNaN(d, x, nil)
  1226  		return true, res, err
  1227  	}
  1228  	if x.Form != Finite {
  1229  		d.Set(x)
  1230  		return true, 0, nil
  1231  	}
  1232  	return false, 0, nil
  1233  }
  1234  
  1235  // RoundToIntegralValue sets d to integral value of x. Inexact and Rounded flags
  1236  // are ignored and removed.
  1237  func (c *Context) RoundToIntegralValue(d, x *Decimal) (Condition, error) {
  1238  	if set, res, err := c.toIntegralSpecials(d, x); set {
  1239  		return res, err
  1240  	}
  1241  	res := c.toIntegral(d, x)
  1242  	res &= ^(Inexact | Rounded)
  1243  	return c.goError(res)
  1244  }
  1245  
  1246  // RoundToIntegralExact sets d to integral value of x.
  1247  func (c *Context) RoundToIntegralExact(d, x *Decimal) (Condition, error) {
  1248  	if set, res, err := c.toIntegralSpecials(d, x); set {
  1249  		return res, err
  1250  	}
  1251  	res := c.toIntegral(d, x)
  1252  	return c.goError(res)
  1253  }
  1254  
  1255  // Ceil sets d to the smallest integer >= x.
  1256  func (c *Context) Ceil(d, x *Decimal) (Condition, error) {
  1257  	var frac Decimal
  1258  	x.Modf(d, &frac)
  1259  	if frac.Sign() > 0 {
  1260  		return c.Add(d, d, decimalOne)
  1261  	}
  1262  	return 0, nil
  1263  }
  1264  
  1265  // Floor sets d to the largest integer <= x.
  1266  func (c *Context) Floor(d, x *Decimal) (Condition, error) {
  1267  	var frac Decimal
  1268  	x.Modf(d, &frac)
  1269  	if frac.Sign() < 0 {
  1270  		return c.Sub(d, d, decimalOne)
  1271  	}
  1272  	return 0, nil
  1273  }
  1274  
  1275  // Reduce sets d to x with all trailing zeros removed and returns the number
  1276  // of zeros removed.
  1277  func (c *Context) Reduce(d, x *Decimal) (int, Condition, error) {
  1278  	if c.shouldSetAsNaN(x, nil) {
  1279  		res, err := c.setAsNaN(d, x, nil)
  1280  		return 0, res, err
  1281  	}
  1282  	neg := x.Negative
  1283  	_, n := d.Reduce(x)
  1284  	d.Negative = neg
  1285  	res := c.round(d, d)
  1286  	res, err := c.goError(res)
  1287  	return n, res, err
  1288  }
  1289  
  1290  // exp10 returns x, 10^x. An error is returned if x is too large.
  1291  // The returned value must not be mutated.
  1292  func exp10(x int64, tmp *BigInt) (exp *BigInt, err error) {
  1293  	if x > MaxExponent || x < MinExponent {
  1294  		return nil, errors.New(errExponentOutOfRangeStr)
  1295  	}
  1296  	return tableExp10(x, tmp), nil
  1297  }
  1298  

View as plain text