mirror of
https://github.com/shopspring/decimal.git
synced 2024-11-22 20:40:48 +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)
|
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:
|
// Cmp compares the numbers represented by d and d2 and returns:
|
||||||
//
|
//
|
||||||
// -1 if d < d2
|
// -1 if d < d2
|
||||||
|
|
|
@ -173,3 +173,13 @@ func Benchmark_decimal_Decimal_Sub_same_precision(b *testing.B) {
|
||||||
d1.Add(d2)
|
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) {
|
func TestDecimal_Sign(t *testing.T) {
|
||||||
if Zero.Sign() != 0 {
|
if Zero.Sign() != 0 {
|
||||||
t.Errorf("%q should have sign 0", Zero)
|
t.Errorf("%q should have sign 0", Zero)
|
||||||
|
|
Loading…
Reference in a new issue