mirror of
https://github.com/shopspring/decimal.git
synced 2024-11-22 12:30:49 +01:00
Implement IsInteger method (#179)
This commit is contained in:
parent
2568a29459
commit
6fe01c1abd
3 changed files with 65 additions and 0 deletions
27
decimal.go
27
decimal.go
|
@ -583,6 +583,33 @@ func (d Decimal) Pow(d2 Decimal) Decimal {
|
|||
return temp.Mul(temp).Div(d)
|
||||
}
|
||||
|
||||
// IsInteger returns true when decimal can be represented as an integer value, otherwise, it returns false.
|
||||
func (d Decimal) IsInteger() bool {
|
||||
// The most typical case, all decimal with exponent higher or equal 0 can be represented as integer
|
||||
if d.exp >= 0 {
|
||||
return true
|
||||
}
|
||||
// When the exponent is negative we have to check every number after the decimal place
|
||||
// If all of them are zeroes, we are sure that given decimal can be represented as an integer
|
||||
var r big.Int
|
||||
q := big.NewInt(0).Set(d.value)
|
||||
for z := abs(d.exp); z > 0; z-- {
|
||||
q.QuoRem(q, tenInt, &r)
|
||||
if r.Cmp(zeroInt) != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Abs calculates absolute value of any int32. Used for calculating absolute value of decimal's exponent.
|
||||
func abs(n int32) int32 {
|
||||
if n < 0 {
|
||||
return -n
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Cmp compares the numbers represented by d and d2 and returns:
|
||||
//
|
||||
// -1 if d < d2
|
||||
|
|
|
@ -173,3 +173,13 @@ func Benchmark_decimal_Decimal_Sub_same_precision(b *testing.B) {
|
|||
d1.Add(d2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecimal_IsInteger(b *testing.B) {
|
||||
d := RequireFromString("12.000")
|
||||
|
||||
b.ReportAllocs()
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
d.IsInteger()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2076,6 +2076,34 @@ func TestNegativePow(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDecimal_IsInteger(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
Dec string
|
||||
IsInteger bool
|
||||
}{
|
||||
{"0", true},
|
||||
{"0.0000", true},
|
||||
{"0.01", false},
|
||||
{"0.01010101010000", false},
|
||||
{"12.0", true},
|
||||
{"12.00000000000000", true},
|
||||
{"12.10000", false},
|
||||
{"9999.0000", true},
|
||||
{"99999999.000000000", true},
|
||||
{"-656323444.0000000000000", true},
|
||||
{"-32768.01234", false},
|
||||
{"-32768.0123423562623600000", false},
|
||||
} {
|
||||
d, err := NewFromString(testCase.Dec)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if d.IsInteger() != testCase.IsInteger {
|
||||
t.Errorf("expect %t, got %t, for %s", testCase.IsInteger, d.IsInteger(), testCase.Dec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecimal_Sign(t *testing.T) {
|
||||
if Zero.Sign() != 0 {
|
||||
t.Errorf("%q should have sign 0", Zero)
|
||||
|
|
Loading…
Reference in a new issue