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

Fix panic for modulo on floating-point numbers #1247

Merged

Conversation

ashutosh-narkar
Copy link
Member

Fixes #1245

Currently modulo operator (%) panics when the input is a floating point number. This change adds support to perform floating-point remainder operation on floating point numbers.

Signed-off-by: Ashutosh Narkar anarkar4387@gmail.com

@ashutosh-narkar ashutosh-narkar requested a review from tsandall March 5, 2019 22:39
"testing"
)

func TestBuiltinRem(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: we have test cases for the mod operator in the topdown_test.go file (search for "remainder")

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the test.

rules []string
expected interface{}
}{
{"integer modulo remainder", []string{`p[x] { x := 1 % 1 }`}, "[0]"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have test cases for error paths.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

_, ok2 = n2.Int()

if ok1 && ok2 {
i, err := arithRem(builtins.NumberToInt(n1), builtins.NumberToInt(n2))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code above is converting to int64 but then this is converting to big.Int and using big.Int's remainder operation (which is a bit odd.)

It doesn't look like like Go's big number package supports remainder operations on big.Float. Implementing the latter requires care. In the short term, let's return an error for mod on floating point numbers and make sure mod on big integers (e.g., numbers that exceed int64 range) produce correct answers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated code to return error if non-integer mod operation is performed.

Copy link
Member

@tsandall tsandall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One nit about the error message and then we can merge.

op2, err2 := builtins.NumberToInt(n2)

if err1 != nil || err2 != nil {
return nil, fmt.Errorf("mod operation supported on integers only")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might just be me, but I think this error reads a bit strange.

If you run this in the REPL, this is what you get:

> 1.1 % 2
1.1 % 2: eval_internal_error: rem: mod operation supported on integers only
modulo on floating-point number

One thing to note is that because we parse integers using big.Float in all cases, large integer values get represented in scientific notation which big.Int doesn't parse. We should file a separate bug to fix that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the error message.

Fixes open-policy-agent#1245

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
@tsandall tsandall changed the title Add support for float modulo remainder operation. Fix panic for modulo on floating-point numbers Mar 8, 2019
@ashutosh-narkar ashutosh-narkar merged commit db922a7 into open-policy-agent:master Mar 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants