Skip to content

Commit

Permalink
allow Modf to not set arguments
Browse files Browse the repository at this point in the history
This closes the linked issue because it is now trivial to implement
trunc and not worth a whole function to do it that's just a wrapper of
modf.

Closes #24
  • Loading branch information
maddyblue committed Jun 30, 2017
1 parent 83a2081 commit da77553
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 16 deletions.
56 changes: 40 additions & 16 deletions decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -677,37 +677,61 @@ func (d *Decimal) IsZero() bool {
}

// Modf sets integ to the integral part of d and frac to the fractional part
// such that d = integ+frac. If d is negative, both integ or frac will be
// either 0 or negative. integ.Exponent will be >= 0; frac.Exponent will be
// <= 0.
// such that d = integ+frac. If d is negative, both integ or frac will be either
// 0 or negative. integ.Exponent will be >= 0; frac.Exponent will be <= 0.
// Either argument can be nil, preventing it from being set.
func (d *Decimal) Modf(integ, frac *Decimal) {
if integ == nil && frac == nil {
return
}

neg := d.Negative

// No fractional part.
if d.Exponent > 0 {
frac.Negative = neg
frac.Exponent = 0
frac.Coeff.SetInt64(0)
integ.Set(d)
if frac != nil {
frac.Negative = neg
frac.Exponent = 0
frac.Coeff.SetInt64(0)
}
if integ != nil {
integ.Set(d)
}
return
}
nd := d.NumDigits()
exp := -int64(d.Exponent)
// d < 0 because exponent is larger than number of digits.
if exp > nd {
integ.Negative = neg
integ.Exponent = 0
integ.Coeff.SetInt64(0)
frac.Set(d)
if integ != nil {
integ.Negative = neg
integ.Exponent = 0
integ.Coeff.SetInt64(0)
}
if frac != nil {
frac.Set(d)
}
return
}

e := tableExp10(exp, nil)
integ.Coeff.QuoRem(&d.Coeff, e, &frac.Coeff)
integ.Exponent = 0
frac.Exponent = d.Exponent
frac.Negative = neg
integ.Negative = neg

var icoeff *big.Int
if integ != nil {
icoeff = &integ.Coeff
integ.Exponent = 0
integ.Negative = neg
} else {
icoeff = new(big.Int)
}

if frac != nil {
icoeff.QuoRem(&d.Coeff, e, &frac.Coeff)
frac.Exponent = d.Exponent
frac.Negative = neg
} else {
icoeff.Quo(&d.Coeff, e)
}
}

// Neg sets d to -x and returns d.
Expand Down
14 changes: 14 additions & 0 deletions decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,22 @@ func TestModf(t *testing.T) {
if frac.Exponent > 0 {
t.Fatal(frac.Exponent)
}

integ2, frac2 := new(Decimal), new(Decimal)
x.Modf(integ2, nil)
x.Modf(nil, frac2)
if integ.CmpTotal(integ2) != 0 {
t.Fatalf("got %s, expected %s", integ2, integ)
}
if frac.CmpTotal(frac2) != 0 {
t.Fatalf("got %s, expected %s", frac2, frac)
}
})
}

// Ensure we don't panic on both nil.
a := new(Decimal)
a.Modf(nil, nil)
}

func TestInt64(t *testing.T) {
Expand Down

0 comments on commit da77553

Please sign in to comment.