Skip to content

Commit

Permalink
Decimal: implement MantExp / SetMantExp
Browse files Browse the repository at this point in the history
  • Loading branch information
db47h committed May 19, 2020
1 parent 8ff337b commit ed7e48b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 19 deletions.
61 changes: 56 additions & 5 deletions decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var decimalZero Decimal

var (
_ fmt.Scanner = &decimalZero // *Decimal must implement fmt.Scanner
_ fmt.Formatter = &decimalZero // *Float must implement fmt.Formatter
_ fmt.Formatter = &decimalZero // *Decimal must implement fmt.Formatter
)

type Decimal struct {
Expand All @@ -33,7 +33,7 @@ type Decimal struct {
neg bool
}

// NewDecimal allocates and returns a new Float set to x, with precision
// NewDecimal allocates and returns a new Decimal set to x, with precision
// DefaultDecimalPrec and rounding mode ToNearestEven. NewDecimal panics with
// ErrNaN if x is a NaN.
func NewDecimal(x float64) *Decimal {
Expand Down Expand Up @@ -601,8 +601,35 @@ func (x *Decimal) IsInt() bool {
return x.prec <= uint32(x.exp) || x.MinPrec() <= uint(x.exp)
}

// MantExp breaks x into its mantissa and exponent components
// and returns the exponent. If a non-nil mant argument is
// provided its value is set to the mantissa of x, with the
// same precision and rounding mode as x. The components
// satisfy x == mant × 10**exp, with 0.1 <= |mant| < 1.0.
// Calling MantExp with a nil argument is an efficient way to
// get the exponent of the receiver.
//
// Special cases are:
//
// ( ±0).MantExp(mant) = 0, with mant set to ±0
// (±Inf).MantExp(mant) = 0, with mant set to ±Inf
//
// x and mant may be the same in which case x is set to its
// mantissa value.
func (x *Decimal) MantExp(mant *Decimal) (exp int) {
panic("not implemented")
if debugDecimal {
x.validate()
}
if x.form == finite {
exp = int(x.exp)
}
if mant != nil {
mant.Copy(x)
if mant.form == finite {
mant.exp = 0
}
}
return
}

func (x *Decimal) MarshalText() (text []byte, err error) {
Expand Down Expand Up @@ -991,8 +1018,32 @@ func (z *Decimal) setExpAndRound(exp int64, sbit uint) {
z.round(sbit)
}

// SetMantExp sets z to mant × 10**exp and returns z.
// The result z has the same precision and rounding mode
// as mant. SetMantExp is an inverse of MantExp but does
// not require 0.1 <= |mant| < 1.0. Specifically:
//
// mant := new(Decimal)
// new(Decimal).SetMantExp(mant, x.MantExp(mant)).Cmp(x) == 0
//
// Special cases are:
//
// z.SetMantExp( ±0, exp) = ±0
// z.SetMantExp(±Inf, exp) = ±Inf
//
// z and mant may be the same in which case z's exponent
// is set to exp.
func (z *Decimal) SetMantExp(mant *Decimal, exp int) *Decimal {
panic("not implemented")
if debugDecimal {
z.validate()
mant.validate()
}
z.Copy(mant)
if z.form != finite {
return z
}
z.setExpAndRound(int64(z.exp)+int64(exp), 0)
return z
}

// SetMode sets z's rounding mode to mode and returns an exact z.
Expand Down Expand Up @@ -1216,7 +1267,7 @@ func (x *Decimal) validate() {
func validateBinaryOperands(x, y *Decimal) {
if !debugDecimal {
// avoid performance bugs
panic("validateBinaryOperands called but debugFloat is not set")
panic("validateBinaryOperands called but debugDecimal is not set")
}
if len(x.mant) == 0 {
panic("empty mantissa for x")
Expand Down
14 changes: 0 additions & 14 deletions decimal_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package decimal

import (
"math"
"math/big"
"math/rand"
"reflect"
Expand Down Expand Up @@ -107,16 +106,3 @@ func BenchmarkDecimal_dnorm(b *testing.B) {
benchU = uint(dnorm(d))
}
}

func TestDecimal_String(t *testing.T) {
z := big.NewFloat(1.1)
t.Logf("z: %g!", z)
// x, _ := new(Decimal).SetPrec(34).SetString("9223372036854775808")
x := new(Decimal).SetPrec(17).SetFloat64(math.MaxFloat64)
// t.Log(x.Text('p', 0))
t.Logf("x: %g!", x)
x.SetPrec(128).SetFloat(z)
t.Logf("z = %g -> x = %g", z, x)
x.Float(z)
t.Logf("x = %g -> z = %g", x, z)
}

0 comments on commit ed7e48b

Please sign in to comment.