Skip to content
This repository has been archived by the owner on Jun 14, 2021. It is now read-only.

Commit

Permalink
Implement IsInteger method (shopspring#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
fairyhunter13 committed Jun 30, 2020
1 parent 085df1c commit 5fbb65f
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
27 changes: 27 additions & 0 deletions decimal.go
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions decimal_bench_test.go
Expand Up @@ -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()
}
}
28 changes: 28 additions & 0 deletions decimal_test.go
Expand Up @@ -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)
Expand Down

0 comments on commit 5fbb65f

Please sign in to comment.