open-policy-agent / opa

Open Policy Agent (OPA) is an open source, general-purpose policy engine.
https://www.openpolicyagent.org
Apache License 2.0
9.36k stars 1.3k forks source link

Big number support unclear with arithmetic operations #6281

Open tsandall opened 9 months ago

tsandall commented 9 months ago

The arithmetic operators use the go math/big library under the hood however we seem to be running into loss-of-precision problems with several test cases. These cases from the rego-cpp implementation fail against topdown: https://raw.githubusercontent.com/microsoft/rego-cpp/main/tests/bigint.yaml

We should either fix topdown to support arithmetic on big numbers or clearly document what's supported (vs what is not.)

ashutosh-narkar commented 9 months ago

It would be good to understand the expected behavior of a particular test case for example. I ran few of the cases in https://raw.githubusercontent.com/microsoft/rego-cpp/main/tests/bigint.yaml and the actual results seems to not lose precision. Maybe I missed something so would be helpful to get more clarification so we can fix the behavior if possible.

ashutosh-narkar commented 9 months ago

@tsandall some more context here would be helpful. Thanks!

matajoh commented 5 months ago

For some context, if I create this Rego file:

package bigint

tadd := -30339405259128826320371676477143698993343796573815996524417845829294351 + 104688599292429000714300283444823567875127199363520643982601892296975006
tsub := -44490570981537590899012122340378398923421348521165077299165008960603759 - 68529429636135486290804721826997958888091459673624581943216947903335757
tmul := 79754341600736016111746705453330145114105289328804738919288096361713471 * 65152214870832516721444134645799134637055145236930890078093265262979414
tdiv := 50780901411816507599004854293945100734566501448333723073581001132421203 / -147863808509682044529515298376380288
tmod := 3582179939697576964326055910334136801174876720124800582552296958781519 % -225198022027540975370394236776633299

a := tadd == 74349194033300174393928606967679868881783402789704647458184046467680655
b := tsub == -113020000617673077189816844167376357811512808194789659242381956863939516
c := tmul == 5196172000852929494850683590287706987412208859683214470294095175794819136418656199328647023359300788882421285414132090957392823251755639485994
d := tdiv == -343430227610371613297784508459153108
e := tmod == 79669604418830368256246356946031314
output = [a, b, c, d, e]

And evaluate it, I get the following result:

{
  "result": [
    {
      "expressions": [
        {
          "value": [
            false,
            false,
            false,
            false,
            false
          ],
          "text": "data.bigint.output",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}
matajoh commented 5 months ago

(I would expect the division to fail, as there is no concept of integer division in the language, but the rest should pass)