Uploaded image for project: 'Documentation'
  1. Documentation
  2. DOCS-7792

$mod silently truncates decimal arguments to integers

    • Type: Icon: Bug Bug
    • Resolution: Won't Fix
    • Priority: Icon: Major - P3 Major - P3
    • Server_Docs_20231030
    • Affects Version/s: mongodb-2.6, mongodb-3.0
    • Component/s: manual, Server
    • Labels:

      The $mod conditional operator casts all its inputs into LONG's before executing the modulo calculation and comparison. This truncates any decimal values back to their integer parts, which causing some users to get unexpected results. For example, if db.collName.f1 holds [0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, ... 9.0, 9.5, 10] then these statements:

        db.collName.find({ "f1": {$mod:[5.5, 2.5]} }) 
        db.collName.find({ "f1": {$mod:[5,    2]} }) 

      both return [2.0, 2.5, 7.0, 7.5] because we don't return the documents where ((f1 % 5.5) == 2.5), we return those where ((floor(f1) % floor(5.5)) == floor(2.5)).

      While I accept that MongoDB does this "integer division" because it stores numbers in binary floating point and floating point calculations are prone to rounding errors, I think that we should make this clearer in the manual entry for $mod (https://docs.mongodb.org/manual/reference/operator/query/mod/). Most users expect that mod will behave the same way as it does in their other databases/applications/programming environments/etc because it is a generic mathematical term.

        1. mod25.js
          1 kB
        2. moddoc.js
          1 kB

            emet.ozar@mongodb.com Emet Ozar
            william.byrne@mongodb.com William Byrne III
            0 Vote for this issue
            7 Start watching this issue

              1 year, 30 weeks ago