Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding RoundUp #194

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions decimal.go
Expand Up @@ -902,6 +902,19 @@ func (d Decimal) RoundBank(places int32) Decimal {
return round
}

// RoundUp rounds decimal number towards positive infinite
// (1.1).RoundUp(0) => 1
// (1.52).RoundUp(1) => 1.6
// (1.1001).RoundUp(2) => 1.11
func (d Decimal) RoundUp(places int32) Decimal {
p := math.Pow(10, float64(places))
f := NewFromFloat(p)
m := d.Mul(f)
n := m.Ceil()
o := n.Div(f)
return o
}

// RoundCash aka Cash/Penny/öre rounding rounds decimal to a specific
// interval. The amount payable for a cash transaction is rounded to the nearest
// multiple of the minimum currency unit available. The following intervals are
Expand Down
6 changes: 6 additions & 0 deletions decimal_bench_test.go
Expand Up @@ -119,6 +119,12 @@ func BenchmarkDecimal_RoundCash_Five(b *testing.B) {
}
}

func BenchmarkDecimal_RoundUp(b *testing.B) {
for i := 0; i < b.N; i++ {
NewFromFloat(10.0012).RoundUp(3)
}
}

func Benchmark_Cmp(b *testing.B) {
decimals := DecimalSlice([]Decimal{})
for i := 0; i < 1000000; i++ {
Expand Down
88 changes: 88 additions & 0 deletions decimal_test.go
Expand Up @@ -994,6 +994,94 @@ func TestDecimal_RoundAndStringFixed(t *testing.T) {
}
}

func TestDecimal_RoundUpAndStringFixed(t *testing.T) {
type testData struct {
input string
places int32
expected string
expectedFixed string
}
tests := []testData{
{"1.454", 0, "2", ""},
{"1.454", 1, "1.5", ""},
{"1.454", 2, "1.46", ""},
{"1.454", 3, "1.454", ""},
{"1.454", 4, "1.454", "1.4540"},
{"1.454", 5, "1.454", "1.45400"},
{"1.554", 0, "2", ""},
{"1.554", 1, "1.6", ""},
{"1.554", 2, "1.56", ""},
{"0.554", 0, "1", ""},
{"0.454", 0, "1", ""},
{"0.454", 5, "0.454", "0.45400"},
{"0", 0, "0", ""},
{"0", 1, "0", "0.0"},
{"0", 2, "0", "0.00"},
{"0", -1, "0", ""},
{"5", 2, "5", "5.00"},
{"5", 1, "5", "5.0"},
{"5", 0, "5", ""},
{"500", 2, "500", "500.00"},
{"545", -1, "550", ""},
{"545", -2, "600", ""},
{"545", -3, "1000", ""},
{"545", -4, "10000", ""},
{"499", -3, "1000", ""},
{"499", -4, "10000", ""},
{"1.1001", 2, "1.11", ""},
{"-1.454", 0, "-1", ""},
{"-1.454", 1, "-1.4", ""},
{"-1.454", 2, "-1.45", ""},
{"-1.454", 3, "-1.454", ""},
{"-1.454", 4, "-1.454", "-1.4540"},
{"-1.454", 5, "-1.454", "-1.45400"},
{"-1.554", 0, "-1", ""},
{"-1.554", 1, "-1.5", ""},
{"-1.554", 2, "-1.55", ""},
{"-0.554", 0, "0", ""},
{"-0.454", 0, "0", ""},
{"-0.454", 5, "-0.454", "-0.45400"},
{"-5", 2, "-5", "-5.00"},
{"-5", 1, "-5", "-5.0"},
{"-5", 0, "-5", ""},
{"-500", 2, "-500", "-500.00"},
{"-545", -1, "-540", ""},
{"-545", -2, "-500", ""},
{"-545", -3, "0", ""},
{"-545", -4, "0", ""},
{"-499", -3, "0", ""},
{"-499", -4, "0", ""},
}

for _, test := range tests {
d, err := NewFromString(test.input)
if err != nil {
panic(err)
}

// test Round
expected, err := NewFromString(test.expected)
if err != nil {
panic(err)
}
got := d.RoundUp(test.places)
if !got.Equal(expected) {
t.Errorf("Rounding Up %s to %d places, got %s, expected %s",
d, test.places, got, expected)
}

// test StringFixed
if test.expectedFixed == "" {
test.expectedFixed = test.expected
}
gotStr := got.StringFixed(test.places)
if gotStr != test.expectedFixed {
t.Errorf("(%s).StringFixed(%d): got %s, expected %s",
d, test.places, gotStr, test.expectedFixed)
}
}
}

func TestDecimal_BankRoundAndStringFixed(t *testing.T) {
type testData struct {
input string
Expand Down