Skip to content

Commit

Permalink
Merge pull request #79 from cockroachdb/bigint
Browse files Browse the repository at this point in the history
improve external set APIs
  • Loading branch information
maddyblue authored Oct 17, 2018
2 parents 9c2ab8e + dd99259 commit 2676f8e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 26 deletions.
2 changes: 1 addition & 1 deletion bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func runBenches(
if _, _, err := nums[i].SetString(buf.String()); err != nil {
b.Fatal(err)
}
nums[i].SetExponent(int32(s - numDigits))
nums[i].Exponent = int32(s - numDigits)
}
b.Run(
fmt.Sprintf("P%d/S%d/D%d", p, s, d),
Expand Down
17 changes: 8 additions & 9 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,13 +496,13 @@ func (c *Context) Sqrt(d, x *Decimal) (Condition, error) {
// is odd or even.
approx := new(Decimal)
if e%2 == 0 {
approx.SetCoefficient(819).SetExponent(-3)
approx.SetFinite(819, -3)
ed.Mul(approx, approx, f)
ed.Add(approx, approx, New(259, -3))
} else {
f.Exponent--
e++
approx.SetCoefficient(259).SetExponent(-2)
approx.SetFinite(259, -2)
ed.Mul(approx, approx, f)
ed.Add(approx, approx, New(819, -4))
}
Expand Down Expand Up @@ -723,7 +723,7 @@ func (c *Context) Ln(d, x *Decimal) (Condition, error) {
// tmp1 = z - 1
ed.Sub(tmp1, z, decimalOne)
// tmp3 = 0.1
tmp3.SetCoefficient(1).SetExponent(-1)
tmp3.SetFinite(1, -1)

usePowerSeries := false

Expand All @@ -737,7 +737,7 @@ func (c *Context) Ln(d, x *Decimal) (Condition, error) {
// We multiplied the input by 10^-expDelta, we will need to add
// ln(10^expDelta) = expDelta * ln(10)
// to the result.
resAdjust.SetCoefficient(int64(expDelta))
resAdjust.setCoefficient(int64(expDelta))
ed.Mul(resAdjust, resAdjust, decimalLn10.get(p))

// tmp1 = z - 1
Expand Down Expand Up @@ -785,7 +785,7 @@ func (c *Context) Ln(d, x *Decimal) (Condition, error) {
ed.Mul(tmp3, tmp3, tmp2)

// tmp4 = 2n+1
tmp4.SetCoefficient(int64(2*n + 1)).SetExponent(0)
tmp4.SetFinite(int64(2*n+1), 0)

ed.Quo(tmp4, tmp3, tmp4)

Expand Down Expand Up @@ -914,15 +914,14 @@ func (c *Context) Exp(d, x *Decimal) (Condition, error) {
if x.Sign() < 0 {
res = res.negateOverflowFlags()
res |= Clamped
d.SetCoefficient(0)
d.Exponent = c.etiny()
d.SetFinite(0, c.etiny())
} else {
d.Set(decimalInfinity)
}
return c.goError(res)
}
// if abs(x) <= setexp(.9, -currentprecision); then result 1
tmp2.SetCoefficient(9).SetExponent(int32(-cp) - 1)
tmp2.SetFinite(9, int32(-cp)-1)
if tmp1.Cmp(tmp2) <= 0 {
d.Set(decimalOne)
return c.goError(res)
Expand Down Expand Up @@ -962,7 +961,7 @@ func (c *Context) Exp(d, x *Decimal) (Condition, error) {
sum := New(1, 0)
tmp2.Exponent = 0
for i := n - 1; i > 0; i-- {
tmp2.SetCoefficient(i)
tmp2.setCoefficient(i)
// tmp1 = r / i
ed.Quo(tmp1, r, tmp2)
// sum = sum * r / i
Expand Down
35 changes: 19 additions & 16 deletions decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,15 @@ func New(coeff int64, exponent int32) *Decimal {

// NewWithBigInt creates a new decimal with the given coefficient and exponent.
func NewWithBigInt(coeff *big.Int, exponent int32) *Decimal {
return &Decimal{
Coeff: *coeff,
d := &Decimal{
Exponent: exponent,
}
d.Coeff.Set(coeff)
if d.Coeff.Sign() < 0 {
d.Negative = true
d.Coeff.Abs(&d.Coeff)
}
return d
}

func consumePrefix(s, prefix string) (string, bool) {
Expand Down Expand Up @@ -226,25 +231,24 @@ func (d *Decimal) Set(x *Decimal) *Decimal {

// SetInt64 sets d to x and returns d.
func (d *Decimal) SetInt64(x int64) *Decimal {
d.SetCoefficient(x)
d.Exponent = 0
return d.SetFinite(x, 0)
}

// SetFinite sets d to x with exponent e and returns d.
func (d *Decimal) SetFinite(x int64, e int32) *Decimal {
d.setCoefficient(x)
d.Exponent = e
return d
}

// SetCoefficient sets d's coefficient and negative value to x, its Form to
// Finite, and returns d. The exponent is not changed.
func (d *Decimal) SetCoefficient(x int64) *Decimal {
// setCoefficient sets d's coefficient and negative value to x and its Form
// to Finite The exponent is not changed. Since the exponent is not changed
// (and this is thus easy to misuse), this is unexported for internal use only.
func (d *Decimal) setCoefficient(x int64) {
d.Negative = x < 0
d.Coeff.SetInt64(x)
d.Coeff.Abs(&d.Coeff)
d.Form = Finite
return d
}

// SetExponent sets d's Exponent value to x and returns d.
func (d *Decimal) SetExponent(x int32) *Decimal {
d.Exponent = x
return d
}

// SetFloat64 sets d's Coefficient and Exponent to x and returns d. d will
Expand Down Expand Up @@ -711,8 +715,7 @@ func (d *Decimal) Reduce(x *Decimal) (*Decimal, int) {
switch x.Sign() {
case 0:
nd = int(d.NumDigits())
d.SetCoefficient(0)
d.Exponent = 0
d.SetInt64(0)
return d, nd - 1
case -1:
neg = true
Expand Down
32 changes: 32 additions & 0 deletions decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,38 @@ func newDecimal(t *testing.T, c *Context, s string) *Decimal {
return d
}

func TestNewWithBigInt(t *testing.T) {
tests := []struct {
d string
b string
}{
{d: "0", b: "0"},
{d: "1", b: "1"},
{d: "-1", b: "-1"},
}
for _, tc := range tests {
t.Run(tc.d, func(t *testing.T) {
expect, _, err := new(Decimal).SetString(tc.d)
if err != nil {
t.Fatal(err)
}
b, ok := new(big.Int).SetString(tc.b, 10)
if !ok {
t.Fatal("bad bigint")
}
d := NewWithBigInt(b, 0)
if d.Coeff.Sign() < 0 {
t.Fatal("unexpected negative coeff")
}
// Verify that changing b doesn't change d.
b.Set(big.NewInt(1234))
if d.CmpTotal(expect) != 0 {
t.Fatalf("expected %s, got %s", expect, d)
}
})
}
}

func TestUpscale(t *testing.T) {
tests := []struct {
x, y *Decimal
Expand Down

0 comments on commit 2676f8e

Please sign in to comment.