Skip to content

Commit

Permalink
Update Float ceil and floor to accept args
Browse files Browse the repository at this point in the history
  • Loading branch information
SD10 committed Mar 10, 2018
1 parent ddb88a8 commit 00f8f21
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 10 deletions.
73 changes: 65 additions & 8 deletions vm/float.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,11 +383,36 @@ func builtinFloatInstanceMethods() []*BuiltinMethodObject {
Name: "ceil",
Fn: func(receiver Object, sourceLine int) builtinMethodBody {
return func(t *thread, args []Object, blockFrame *normalCallFrame) Object {
if len(args) > 1 {
return t.vm.initErrorObject(errors.ArgumentError, sourceLine, "Expect 1 integer arguements. got=%d", len(args))
}

r := receiver.(*FloatObject)
result := math.Ceil(r.value)
newInt := t.vm.initIntegerObject(int(result))
newInt.flag = i
return newInt

if len(args) == 0 {
result := math.Ceil(r.value)
newInt := t.vm.initIntegerObject(int(result))
newInt.flag = i
return newInt
}

p, ok := args[0].(*IntegerObject)

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

shift := math.Pow10(p.value)
shifted := r.value * shift
result := math.Ceil(shifted) / shift

if p.value <= 0 {
newInt := t.vm.initIntegerObject(int(result))
newInt.flag = i
return newInt
}

return t.vm.initFloatObject(result)
}
},
},
Expand All @@ -404,11 +429,35 @@ func builtinFloatInstanceMethods() []*BuiltinMethodObject {
Name: "floor",
Fn: func(receiver Object, sourceLine int) builtinMethodBody {
return func(t *thread, args []Object, blockFrame *normalCallFrame) Object {
if len(args) > 1 {
return t.vm.initErrorObject(errors.ArgumentError, sourceLine, "Expect 1 integer arguements. got=%d", len(args))
}

r := receiver.(*FloatObject)
result := math.Floor(r.value)
newInt := t.vm.initIntegerObject(int(result))
newInt.flag = i
return newInt

if len(args) == 0 {
result := math.Floor(r.value)
newInt := t.vm.initIntegerObject(int(result))
newInt.flag = i
return newInt
}

p, ok := args[0].(*IntegerObject)

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

shift := math.Pow(10, float64(p.value))
shifted := r.value * shift
result := math.Floor(shifted) / shift

if p.value <= 0 {
newInt := t.vm.initIntegerObject(int(result))
newInt.flag = i
return newInt
}
return t.vm.initFloatObject(result)
}
},
},
Expand Down Expand Up @@ -513,3 +562,11 @@ func (f *FloatObject) toJSON(t *thread) string {
func (f *FloatObject) equal(e *FloatObject) bool {
return f.value == e.value
}

// Math helper functions ------------------------------------------------

// Rounds a float64 to a given place in integers
func roundPlaces(f float64, places int) float64 {
shift := math.Pow(f, float64(places))
return math.Floor(f+0.5) / shift
}
30 changes: 28 additions & 2 deletions vm/float_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,8 @@ func TestFloatAbs(t *testing.T) {
input string
expected interface{}
}{
{"3.14.abs", 3.14},
{"-1.23.abs", 1.23},
{"34.56.abs", 34.56},
{"-34.56.abs", 34.56},
}

for i, tt := range tests {
Expand All @@ -294,6 +294,19 @@ func TestFloatCeil(t *testing.T) {
{"2.0.ceil", 2},
{"-1.2.ceil", -1},
{"-2.0.ceil", -2},
{"1.234567.ceil(2)", 1.24},
{"1.234567.ceil(3)", 1.235},
{"1.234567.ceil(4)", 1.2346},
{"1.234567.ceil(5)", 1.23457},
{"34567.89.ceil(-5)", 99999}, // TODO: This is 100000 in Ruby
{"34567.89.ceil(-4)", 40000},
{"34567.89.ceil(-3)", 35000},
{"34567.89.ceil(-2)", 34600},
{"34567.89.ceil(-1)", 34570},
{"34567.89.ceil(0)", 34568},
{"34567.89.ceil(1)", 34567.9},
{"34567.89.ceil(2)", 34567.89},
{"34567.89.ceil(3)", 34567.89},
}

for i, tt := range tests {
Expand All @@ -314,6 +327,19 @@ func TestFloatFloor(t *testing.T) {
{"2.0.floor", 2},
{"-1.2.floor", -2},
{"-2.0.floor", -2},
{"1.234567.floor(2)", 1.23},
{"1.234567.floor(3)", 1.234},
{"1.234567.floor(4)", 1.2345},
{"1.234567.floor(5)", 1.23456},
{"34567.89.floor(-5)", 0},
{"34567.89.floor(-4)", 30000},
{"34567.89.floor(-3)", 34000},
{"34567.89.floor(-2)", 34500},
{"34567.89.floor(-1)", 34560},
{"34567.89.floor(0)", 34567},
{"34567.89.floor(1)", 34567.8},
{"34567.89.floor(2)", 34567.89},
{"34567.89.floor(3)", 34567.89},
}

for i, tt := range tests {
Expand Down

0 comments on commit 00f8f21

Please sign in to comment.