...

Source file src/gopkg.in/inf.v0/dec.go

Documentation: gopkg.in/inf.v0

     1  // Package inf (type inf.Dec) implements "infinite-precision" decimal
     2  // arithmetic.
     3  // "Infinite precision" describes two characteristics: practically unlimited
     4  // precision for decimal number representation and no support for calculating
     5  // with any specific fixed precision.
     6  // (Although there is no practical limit on precision, inf.Dec can only
     7  // represent finite decimals.)
     8  //
     9  // This package is currently in experimental stage and the API may change.
    10  //
    11  // This package does NOT support:
    12  //  - rounding to specific precisions (as opposed to specific decimal positions)
    13  //  - the notion of context (each rounding must be explicit)
    14  //  - NaN and Inf values, and distinguishing between positive and negative zero
    15  //  - conversions to and from float32/64 types
    16  //
    17  // Features considered for possible addition:
    18  //  + formatting options
    19  //  + Exp method
    20  //  + combined operations such as AddRound/MulAdd etc
    21  //  + exchanging data in decimal32/64/128 formats
    22  //
    23  package inf // import "gopkg.in/inf.v0"
    24  
    25  // TODO:
    26  //  - avoid excessive deep copying (quo and rounders)
    27  
    28  import (
    29  	"fmt"
    30  	"io"
    31  	"math/big"
    32  	"strings"
    33  )
    34  
    35  // A Dec represents a signed arbitrary-precision decimal.
    36  // It is a combination of a sign, an arbitrary-precision integer coefficient
    37  // value, and a signed fixed-precision exponent value.
    38  // The sign and the coefficient value are handled together as a signed value
    39  // and referred to as the unscaled value.
    40  // (Positive and negative zero values are not distinguished.)
    41  // Since the exponent is most commonly non-positive, it is handled in negated
    42  // form and referred to as scale.
    43  //
    44  // The mathematical value of a Dec equals:
    45  //
    46  //  unscaled * 10**(-scale)
    47  //
    48  // Note that different Dec representations may have equal mathematical values.
    49  //
    50  //  unscaled  scale  String()
    51  //  -------------------------
    52  //         0      0    "0"
    53  //         0      2    "0.00"
    54  //         0     -2    "0"
    55  //         1      0    "1"
    56  //       100      2    "1.00"
    57  //        10      0   "10"
    58  //         1     -1   "10"
    59  //
    60  // The zero value for a Dec represents the value 0 with scale 0.
    61  //
    62  // Operations are typically performed through the *Dec type.
    63  // The semantics of the assignment operation "=" for "bare" Dec values is
    64  // undefined and should not be relied on.
    65  //
    66  // Methods are typically of the form:
    67  //
    68  //	func (z *Dec) Op(x, y *Dec) *Dec
    69  //
    70  // and implement operations z = x Op y with the result as receiver; if it
    71  // is one of the operands it may be overwritten (and its memory reused).
    72  // To enable chaining of operations, the result is also returned. Methods
    73  // returning a result other than *Dec take one of the operands as the receiver.
    74  //
    75  // A "bare" Quo method (quotient / division operation) is not provided, as the
    76  // result is not always a finite decimal and thus in general cannot be
    77  // represented as a Dec.
    78  // Instead, in the common case when rounding is (potentially) necessary,
    79  // QuoRound should be used with a Scale and a Rounder.
    80  // QuoExact or QuoRound with RoundExact can be used in the special cases when it
    81  // is known that the result is always a finite decimal.
    82  //
    83  type Dec struct {
    84  	unscaled big.Int
    85  	scale    Scale
    86  }
    87  
    88  // Scale represents the type used for the scale of a Dec.
    89  type Scale int32
    90  
    91  const scaleSize = 4 // bytes in a Scale value
    92  
    93  // Scaler represents a method for obtaining the scale to use for the result of
    94  // an operation on x and y.
    95  type scaler interface {
    96  	Scale(x *Dec, y *Dec) Scale
    97  }
    98  
    99  var bigInt = [...]*big.Int{
   100  	big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4),
   101  	big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9),
   102  	big.NewInt(10),
   103  }
   104  
   105  var exp10cache [64]big.Int = func() [64]big.Int {
   106  	e10, e10i := [64]big.Int{}, bigInt[1]
   107  	for i := range e10 {
   108  		e10[i].Set(e10i)
   109  		e10i = new(big.Int).Mul(e10i, bigInt[10])
   110  	}
   111  	return e10
   112  }()
   113  
   114  // NewDec allocates and returns a new Dec set to the given int64 unscaled value
   115  // and scale.
   116  func NewDec(unscaled int64, scale Scale) *Dec {
   117  	return new(Dec).SetUnscaled(unscaled).SetScale(scale)
   118  }
   119  
   120  // NewDecBig allocates and returns a new Dec set to the given *big.Int unscaled
   121  // value and scale.
   122  func NewDecBig(unscaled *big.Int, scale Scale) *Dec {
   123  	return new(Dec).SetUnscaledBig(unscaled).SetScale(scale)
   124  }
   125  
   126  // Scale returns the scale of x.
   127  func (x *Dec) Scale() Scale {
   128  	return x.scale
   129  }
   130  
   131  // Unscaled returns the unscaled value of x for u and true for ok when the
   132  // unscaled value can be represented as int64; otherwise it returns an undefined
   133  // int64 value for u and false for ok. Use x.UnscaledBig().Int64() to avoid
   134  // checking the validity of the value when the check is known to be redundant.
   135  func (x *Dec) Unscaled() (u int64, ok bool) {
   136  	u = x.unscaled.Int64()
   137  	var i big.Int
   138  	ok = i.SetInt64(u).Cmp(&x.unscaled) == 0
   139  	return
   140  }
   141  
   142  // UnscaledBig returns the unscaled value of x as *big.Int.
   143  func (x *Dec) UnscaledBig() *big.Int {
   144  	return &x.unscaled
   145  }
   146  
   147  // SetScale sets the scale of z, with the unscaled value unchanged, and returns
   148  // z.
   149  // The mathematical value of the Dec changes as if it was multiplied by
   150  // 10**(oldscale-scale).
   151  func (z *Dec) SetScale(scale Scale) *Dec {
   152  	z.scale = scale
   153  	return z
   154  }
   155  
   156  // SetUnscaled sets the unscaled value of z, with the scale unchanged, and
   157  // returns z.
   158  func (z *Dec) SetUnscaled(unscaled int64) *Dec {
   159  	z.unscaled.SetInt64(unscaled)
   160  	return z
   161  }
   162  
   163  // SetUnscaledBig sets the unscaled value of z, with the scale unchanged, and
   164  // returns z.
   165  func (z *Dec) SetUnscaledBig(unscaled *big.Int) *Dec {
   166  	z.unscaled.Set(unscaled)
   167  	return z
   168  }
   169  
   170  // Set sets z to the value of x and returns z.
   171  // It does nothing if z == x.
   172  func (z *Dec) Set(x *Dec) *Dec {
   173  	if z != x {
   174  		z.SetUnscaledBig(x.UnscaledBig())
   175  		z.SetScale(x.Scale())
   176  	}
   177  	return z
   178  }
   179  
   180  // Sign returns:
   181  //
   182  //	-1 if x <  0
   183  //	 0 if x == 0
   184  //	+1 if x >  0
   185  //
   186  func (x *Dec) Sign() int {
   187  	return x.UnscaledBig().Sign()
   188  }
   189  
   190  // Neg sets z to -x and returns z.
   191  func (z *Dec) Neg(x *Dec) *Dec {
   192  	z.SetScale(x.Scale())
   193  	z.UnscaledBig().Neg(x.UnscaledBig())
   194  	return z
   195  }
   196  
   197  // Cmp compares x and y and returns:
   198  //
   199  //   -1 if x <  y
   200  //    0 if x == y
   201  //   +1 if x >  y
   202  //
   203  func (x *Dec) Cmp(y *Dec) int {
   204  	xx, yy := upscale(x, y)
   205  	return xx.UnscaledBig().Cmp(yy.UnscaledBig())
   206  }
   207  
   208  // Abs sets z to |x| (the absolute value of x) and returns z.
   209  func (z *Dec) Abs(x *Dec) *Dec {
   210  	z.SetScale(x.Scale())
   211  	z.UnscaledBig().Abs(x.UnscaledBig())
   212  	return z
   213  }
   214  
   215  // Add sets z to the sum x+y and returns z.
   216  // The scale of z is the greater of the scales of x and y.
   217  func (z *Dec) Add(x, y *Dec) *Dec {
   218  	xx, yy := upscale(x, y)
   219  	z.SetScale(xx.Scale())
   220  	z.UnscaledBig().Add(xx.UnscaledBig(), yy.UnscaledBig())
   221  	return z
   222  }
   223  
   224  // Sub sets z to the difference x-y and returns z.
   225  // The scale of z is the greater of the scales of x and y.
   226  func (z *Dec) Sub(x, y *Dec) *Dec {
   227  	xx, yy := upscale(x, y)
   228  	z.SetScale(xx.Scale())
   229  	z.UnscaledBig().Sub(xx.UnscaledBig(), yy.UnscaledBig())
   230  	return z
   231  }
   232  
   233  // Mul sets z to the product x*y and returns z.
   234  // The scale of z is the sum of the scales of x and y.
   235  func (z *Dec) Mul(x, y *Dec) *Dec {
   236  	z.SetScale(x.Scale() + y.Scale())
   237  	z.UnscaledBig().Mul(x.UnscaledBig(), y.UnscaledBig())
   238  	return z
   239  }
   240  
   241  // Round sets z to the value of x rounded to Scale s using Rounder r, and
   242  // returns z.
   243  func (z *Dec) Round(x *Dec, s Scale, r Rounder) *Dec {
   244  	return z.QuoRound(x, NewDec(1, 0), s, r)
   245  }
   246  
   247  // QuoRound sets z to the quotient x/y, rounded using the given Rounder to the
   248  // specified scale.
   249  //
   250  // If the rounder is RoundExact but the result can not be expressed exactly at
   251  // the specified scale, QuoRound returns nil, and the value of z is undefined.
   252  //
   253  // There is no corresponding Div method; the equivalent can be achieved through
   254  // the choice of Rounder used.
   255  //
   256  func (z *Dec) QuoRound(x, y *Dec, s Scale, r Rounder) *Dec {
   257  	return z.quo(x, y, sclr{s}, r)
   258  }
   259  
   260  func (z *Dec) quo(x, y *Dec, s scaler, r Rounder) *Dec {
   261  	scl := s.Scale(x, y)
   262  	var zzz *Dec
   263  	if r.UseRemainder() {
   264  		zz, rA, rB := new(Dec).quoRem(x, y, scl, true, new(big.Int), new(big.Int))
   265  		zzz = r.Round(new(Dec), zz, rA, rB)
   266  	} else {
   267  		zz, _, _ := new(Dec).quoRem(x, y, scl, false, nil, nil)
   268  		zzz = r.Round(new(Dec), zz, nil, nil)
   269  	}
   270  	if zzz == nil {
   271  		return nil
   272  	}
   273  	return z.Set(zzz)
   274  }
   275  
   276  // QuoExact sets z to the quotient x/y and returns z when x/y is a finite
   277  // decimal. Otherwise it returns nil and the value of z is undefined.
   278  //
   279  // The scale of a non-nil result is "x.Scale() - y.Scale()" or greater; it is
   280  // calculated so that the remainder will be zero whenever x/y is a finite
   281  // decimal.
   282  func (z *Dec) QuoExact(x, y *Dec) *Dec {
   283  	return z.quo(x, y, scaleQuoExact{}, RoundExact)
   284  }
   285  
   286  // quoRem sets z to the quotient x/y with the scale s, and if useRem is true,
   287  // it sets remNum and remDen to the numerator and denominator of the remainder.
   288  // It returns z, remNum and remDen.
   289  //
   290  // The remainder is normalized to the range -1 < r < 1 to simplify rounding;
   291  // that is, the results satisfy the following equation:
   292  //
   293  //  x / y = z + (remNum/remDen) * 10**(-z.Scale())
   294  //
   295  // See Rounder for more details about rounding.
   296  //
   297  func (z *Dec) quoRem(x, y *Dec, s Scale, useRem bool,
   298  	remNum, remDen *big.Int) (*Dec, *big.Int, *big.Int) {
   299  	// difference (required adjustment) compared to "canonical" result scale
   300  	shift := s - (x.Scale() - y.Scale())
   301  	// pointers to adjusted unscaled dividend and divisor
   302  	var ix, iy *big.Int
   303  	switch {
   304  	case shift > 0:
   305  		// increased scale: decimal-shift dividend left
   306  		ix = new(big.Int).Mul(x.UnscaledBig(), exp10(shift))
   307  		iy = y.UnscaledBig()
   308  	case shift < 0:
   309  		// decreased scale: decimal-shift divisor left
   310  		ix = x.UnscaledBig()
   311  		iy = new(big.Int).Mul(y.UnscaledBig(), exp10(-shift))
   312  	default:
   313  		ix = x.UnscaledBig()
   314  		iy = y.UnscaledBig()
   315  	}
   316  	// save a copy of iy in case it to be overwritten with the result
   317  	iy2 := iy
   318  	if iy == z.UnscaledBig() {
   319  		iy2 = new(big.Int).Set(iy)
   320  	}
   321  	// set scale
   322  	z.SetScale(s)
   323  	// set unscaled
   324  	if useRem {
   325  		// Int division
   326  		_, intr := z.UnscaledBig().QuoRem(ix, iy, new(big.Int))
   327  		// set remainder
   328  		remNum.Set(intr)
   329  		remDen.Set(iy2)
   330  	} else {
   331  		z.UnscaledBig().Quo(ix, iy)
   332  	}
   333  	return z, remNum, remDen
   334  }
   335  
   336  type sclr struct{ s Scale }
   337  
   338  func (s sclr) Scale(x, y *Dec) Scale {
   339  	return s.s
   340  }
   341  
   342  type scaleQuoExact struct{}
   343  
   344  func (sqe scaleQuoExact) Scale(x, y *Dec) Scale {
   345  	rem := new(big.Rat).SetFrac(x.UnscaledBig(), y.UnscaledBig())
   346  	f2, f5 := factor2(rem.Denom()), factor(rem.Denom(), bigInt[5])
   347  	var f10 Scale
   348  	if f2 > f5 {
   349  		f10 = Scale(f2)
   350  	} else {
   351  		f10 = Scale(f5)
   352  	}
   353  	return x.Scale() - y.Scale() + f10
   354  }
   355  
   356  func factor(n *big.Int, p *big.Int) int {
   357  	// could be improved for large factors
   358  	d, f := n, 0
   359  	for {
   360  		dd, dm := new(big.Int).DivMod(d, p, new(big.Int))
   361  		if dm.Sign() == 0 {
   362  			f++
   363  			d = dd
   364  		} else {
   365  			break
   366  		}
   367  	}
   368  	return f
   369  }
   370  
   371  func factor2(n *big.Int) int {
   372  	// could be improved for large factors
   373  	f := 0
   374  	for ; n.Bit(f) == 0; f++ {
   375  	}
   376  	return f
   377  }
   378  
   379  func upscale(a, b *Dec) (*Dec, *Dec) {
   380  	if a.Scale() == b.Scale() {
   381  		return a, b
   382  	}
   383  	if a.Scale() > b.Scale() {
   384  		bb := b.rescale(a.Scale())
   385  		return a, bb
   386  	}
   387  	aa := a.rescale(b.Scale())
   388  	return aa, b
   389  }
   390  
   391  func exp10(x Scale) *big.Int {
   392  	if int(x) < len(exp10cache) {
   393  		return &exp10cache[int(x)]
   394  	}
   395  	return new(big.Int).Exp(bigInt[10], big.NewInt(int64(x)), nil)
   396  }
   397  
   398  func (x *Dec) rescale(newScale Scale) *Dec {
   399  	shift := newScale - x.Scale()
   400  	switch {
   401  	case shift < 0:
   402  		e := exp10(-shift)
   403  		return NewDecBig(new(big.Int).Quo(x.UnscaledBig(), e), newScale)
   404  	case shift > 0:
   405  		e := exp10(shift)
   406  		return NewDecBig(new(big.Int).Mul(x.UnscaledBig(), e), newScale)
   407  	}
   408  	return x
   409  }
   410  
   411  var zeros = []byte("00000000000000000000000000000000" +
   412  	"00000000000000000000000000000000")
   413  var lzeros = Scale(len(zeros))
   414  
   415  func appendZeros(s []byte, n Scale) []byte {
   416  	for i := Scale(0); i < n; i += lzeros {
   417  		if n > i+lzeros {
   418  			s = append(s, zeros...)
   419  		} else {
   420  			s = append(s, zeros[0:n-i]...)
   421  		}
   422  	}
   423  	return s
   424  }
   425  
   426  func (x *Dec) String() string {
   427  	if x == nil {
   428  		return "<nil>"
   429  	}
   430  	scale := x.Scale()
   431  	s := []byte(x.UnscaledBig().String())
   432  	if scale <= 0 {
   433  		if scale != 0 && x.unscaled.Sign() != 0 {
   434  			s = appendZeros(s, -scale)
   435  		}
   436  		return string(s)
   437  	}
   438  	negbit := Scale(-((x.Sign() - 1) / 2))
   439  	// scale > 0
   440  	lens := Scale(len(s))
   441  	if lens-negbit <= scale {
   442  		ss := make([]byte, 0, scale+2)
   443  		if negbit == 1 {
   444  			ss = append(ss, '-')
   445  		}
   446  		ss = append(ss, '0', '.')
   447  		ss = appendZeros(ss, scale-lens+negbit)
   448  		ss = append(ss, s[negbit:]...)
   449  		return string(ss)
   450  	}
   451  	// lens > scale
   452  	ss := make([]byte, 0, lens+1)
   453  	ss = append(ss, s[:lens-scale]...)
   454  	ss = append(ss, '.')
   455  	ss = append(ss, s[lens-scale:]...)
   456  	return string(ss)
   457  }
   458  
   459  // Format is a support routine for fmt.Formatter. It accepts the decimal
   460  // formats 'd' and 'f', and handles both equivalently.
   461  // Width, precision, flags and bases 2, 8, 16 are not supported.
   462  func (x *Dec) Format(s fmt.State, ch rune) {
   463  	if ch != 'd' && ch != 'f' && ch != 'v' && ch != 's' {
   464  		fmt.Fprintf(s, "%%!%c(dec.Dec=%s)", ch, x.String())
   465  		return
   466  	}
   467  	fmt.Fprintf(s, x.String())
   468  }
   469  
   470  func (z *Dec) scan(r io.RuneScanner) (*Dec, error) {
   471  	unscaled := make([]byte, 0, 256) // collects chars of unscaled as bytes
   472  	dp, dg := -1, -1                 // indexes of decimal point, first digit
   473  loop:
   474  	for {
   475  		ch, _, err := r.ReadRune()
   476  		if err == io.EOF {
   477  			break loop
   478  		}
   479  		if err != nil {
   480  			return nil, err
   481  		}
   482  		switch {
   483  		case ch == '+' || ch == '-':
   484  			if len(unscaled) > 0 || dp >= 0 { // must be first character
   485  				r.UnreadRune()
   486  				break loop
   487  			}
   488  		case ch == '.':
   489  			if dp >= 0 {
   490  				r.UnreadRune()
   491  				break loop
   492  			}
   493  			dp = len(unscaled)
   494  			continue // don't add to unscaled
   495  		case ch >= '0' && ch <= '9':
   496  			if dg == -1 {
   497  				dg = len(unscaled)
   498  			}
   499  		default:
   500  			r.UnreadRune()
   501  			break loop
   502  		}
   503  		unscaled = append(unscaled, byte(ch))
   504  	}
   505  	if dg == -1 {
   506  		return nil, fmt.Errorf("no digits read")
   507  	}
   508  	if dp >= 0 {
   509  		z.SetScale(Scale(len(unscaled) - dp))
   510  	} else {
   511  		z.SetScale(0)
   512  	}
   513  	_, ok := z.UnscaledBig().SetString(string(unscaled), 10)
   514  	if !ok {
   515  		return nil, fmt.Errorf("invalid decimal: %s", string(unscaled))
   516  	}
   517  	return z, nil
   518  }
   519  
   520  // SetString sets z to the value of s, interpreted as a decimal (base 10),
   521  // and returns z and a boolean indicating success. The scale of z is the
   522  // number of digits after the decimal point (including any trailing 0s),
   523  // or 0 if there is no decimal point. If SetString fails, the value of z
   524  // is undefined but the returned value is nil.
   525  func (z *Dec) SetString(s string) (*Dec, bool) {
   526  	r := strings.NewReader(s)
   527  	_, err := z.scan(r)
   528  	if err != nil {
   529  		return nil, false
   530  	}
   531  	_, _, err = r.ReadRune()
   532  	if err != io.EOF {
   533  		return nil, false
   534  	}
   535  	// err == io.EOF => scan consumed all of s
   536  	return z, true
   537  }
   538  
   539  // Scan is a support routine for fmt.Scanner; it sets z to the value of
   540  // the scanned number. It accepts the decimal formats 'd' and 'f', and
   541  // handles both equivalently. Bases 2, 8, 16 are not supported.
   542  // The scale of z is the number of digits after the decimal point
   543  // (including any trailing 0s), or 0 if there is no decimal point.
   544  func (z *Dec) Scan(s fmt.ScanState, ch rune) error {
   545  	if ch != 'd' && ch != 'f' && ch != 's' && ch != 'v' {
   546  		return fmt.Errorf("Dec.Scan: invalid verb '%c'", ch)
   547  	}
   548  	s.SkipSpace()
   549  	_, err := z.scan(s)
   550  	return err
   551  }
   552  
   553  // Gob encoding version
   554  const decGobVersion byte = 1
   555  
   556  func scaleBytes(s Scale) []byte {
   557  	buf := make([]byte, scaleSize)
   558  	i := scaleSize
   559  	for j := 0; j < scaleSize; j++ {
   560  		i--
   561  		buf[i] = byte(s)
   562  		s >>= 8
   563  	}
   564  	return buf
   565  }
   566  
   567  func scale(b []byte) (s Scale) {
   568  	for j := 0; j < scaleSize; j++ {
   569  		s <<= 8
   570  		s |= Scale(b[j])
   571  	}
   572  	return
   573  }
   574  
   575  // GobEncode implements the gob.GobEncoder interface.
   576  func (x *Dec) GobEncode() ([]byte, error) {
   577  	buf, err := x.UnscaledBig().GobEncode()
   578  	if err != nil {
   579  		return nil, err
   580  	}
   581  	buf = append(append(buf, scaleBytes(x.Scale())...), decGobVersion)
   582  	return buf, nil
   583  }
   584  
   585  // GobDecode implements the gob.GobDecoder interface.
   586  func (z *Dec) GobDecode(buf []byte) error {
   587  	if len(buf) == 0 {
   588  		return fmt.Errorf("Dec.GobDecode: no data")
   589  	}
   590  	b := buf[len(buf)-1]
   591  	if b != decGobVersion {
   592  		return fmt.Errorf("Dec.GobDecode: encoding version %d not supported", b)
   593  	}
   594  	l := len(buf) - scaleSize - 1
   595  	err := z.UnscaledBig().GobDecode(buf[:l])
   596  	if err != nil {
   597  		return err
   598  	}
   599  	z.SetScale(scale(buf[l : l+scaleSize]))
   600  	return nil
   601  }
   602  
   603  // MarshalText implements the encoding.TextMarshaler interface.
   604  func (x *Dec) MarshalText() ([]byte, error) {
   605  	return []byte(x.String()), nil
   606  }
   607  
   608  // UnmarshalText implements the encoding.TextUnmarshaler interface.
   609  func (z *Dec) UnmarshalText(data []byte) error {
   610  	_, ok := z.SetString(string(data))
   611  	if !ok {
   612  		return fmt.Errorf("invalid inf.Dec")
   613  	}
   614  	return nil
   615  }
   616  

View as plain text