Skip to content

Commit

Permalink
Add Float#round method.
Browse files Browse the repository at this point in the history
  • Loading branch information
st0012 committed Apr 21, 2020
1 parent 77e3229 commit 86f94a0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
34 changes: 34 additions & 0 deletions vm/float.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,40 @@ var builtinFloatInstanceMethods = []*BuiltinMethodObject{
return toBooleanObject(r.value < 0.0)
},
},
{
// Rounds float to a given precision in decimal digits (default 0 digits)
//
// ```Ruby
// 1.115.round # => 1
// 1.115.round(1) # => 1.1
// 1.115.round(2) # => 1.12
// -1.115.round # => -1
// -1.115.round(1) # => -1.1
// -1.115.round(2) # => -1.12
// ```
// @return [Integer]
Name: "round",
Fn: func(receiver Object, sourceLine int, t *Thread, args []Object, blockFrame *normalCallFrame) Object {
var precision int

if len(args) > 1 {
return t.vm.InitErrorObject(errors.ArgumentError, sourceLine, "Expect 0 or 1 argument. got=%v", strconv.Itoa(len(args)))
} else if len(args) == 1 {
int, ok := args[0].(*IntegerObject)

if !ok {
return t.vm.InitErrorObject(errors.TypeError, sourceLine, errors.WrongArgumentTypeFormat, classes.IntegerClass, args[0].Class().Name)
}

precision = int.value
}

f := receiver.(*FloatObject).floatValue()
n := math.Pow10(precision)

return t.vm.initFloatObject(math.Round(f*n) / n)
},
},
}

// Internal functions ===================================================
Expand Down
26 changes: 25 additions & 1 deletion vm/float_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ func TestFloatNumberOfDigit(t *testing.T) {
v.checkSP(t, i, 1)
}
}

// API tests

func TestFloatAbs(t *testing.T) {
Expand Down Expand Up @@ -482,6 +483,30 @@ func TestFloatPositive(t *testing.T) {
}
}

func TestFloatRound(t *testing.T) {
tests := []struct {
input string
expected interface{}
}{
{"1.115.round", 1.0},
{"1.115.round(1)", 1.1},
{"1.115.round(2)", 1.12},
{"-1.115.round", -1.0},
{"-1.115.round(1)", -1.1},
{"-1.115.round(2)", -1.12},
{"1.115.round(-1)", 0.0},
{"-1.115.round(-1)", 0.0},
}

for i, tt := range tests {
v := initTestVM()
evaluated := v.testEval(t, tt.input, getFilename())
VerifyExpected(t, i, evaluated, tt.expected)
v.checkCFP(t, i, 0)
v.checkSP(t, i, 1)
}
}

func TestFloatZero(t *testing.T) {
tests := []struct {
input string
Expand All @@ -499,4 +524,3 @@ func TestFloatZero(t *testing.T) {
v.checkSP(t, i, 1)
}
}

0 comments on commit 86f94a0

Please sign in to comment.