Understanding $round

Hi
In the mongodb docs it states:

When rounding on a value of 5 , $round rounds to the nearest even value.
https://www.mongodb.com/docs/manual/reference/operator/aggregation/round/#rounding-to-even-values

However, when checking the following aggregation example:

[{$project: {
   '1905': {$round: [1905,-1]},
   '1915': {$round: [1915,-1]},
   '1925': {$round: [1925,-1]},
   '1935': {$round: [1935,-1]},
   '1945': {$round: [1945,-1]},
   '1955': {$round: [1955,-1]},
   '1965': {$round: [1965,-1]},
   '1975': {$round: [1975,-1]},
   '1985': {$round: [1985,-1]},
   '1995': {$round: [1995,-1]},
   '190,5': {$round: [190.5,0]},
   '191,5': {$round: [191.5,0]},
   '192,5': {$round: [192.5,0]},
   '193,5': {$round: [193.5,0]},
   '194,5': {$round: [194.5,0]},
   '195,5': {$round: [195.5,0]},
   '196,5': {$round: [196.5,0]},
   '197,5': {$round: [197.5,0]},
   '198,5': {$round: [198.5,0]},
   '199,5': {$round: [199.5,0]},
   '19,05': {$round: [19.05,1]},
   '19,15': {$round: [19.15,1]},
   '19,25': {$round: [19.25,1]},
   '19,35': {$round: [19.35,1]},
   '19,45': {$round: [19.45,1]},
   '19,55': {$round: [19.55,1]},
   '19,65': {$round: [19.65,1]},
   '19,75': {$round: [19.75,1]},
   '19,85': {$round: [19.85,1]},
   '19,95': {$round: [19.95,1]},
   '19,005': {$round: [19.005,2]},
   '19,015': {$round: [19.015,2]},
   '19,025': {$round: [19.025,2]},
   '19,035': {$round: [19.035,2]},
   '19,045': {$round: [19.045,2]},
   '19,055': {$round: [19.055,2]},
   '19,065': {$round: [19.065,2]},
   '19,075': {$round: [19.075,2]},
   '19,085': {$round: [19.085,2]},
   '19,095': {$round: [19.095,2]},
   '19,0005': {$round: [19.0005,3]},
   '19,0015': {$round: [19.0015,3]},
   '19,0025': {$round: [19.0025,3]},
   '19,0035': {$round: [19.0035,3]},
   '19,0045': {$round: [19.0045,3]},
   '19,0055': {$round: [19.0055,3]},
   '19,0065': {$round: [19.0065,3]},
   '19,0075': {$round: [19.0075,3]},
   '19,0085': {$round: [19.0085,3]},
   '19,0095': {$round: [19.0095,3]},
   '19,00005': {$round: [19.00005,4]},
   '19,00015': {$round: [19.00015,4]},
   '19,00025': {$round: [19.00025,4]},
   '19,00035': {$round: [19.00035,4]},
   '19,00045': {$round: [19.00045,4]},
   '19,00055': {$round: [19.00055,4]},
   '19,00065': {$round: [19.00065,4]},
   '19,00075': {$round: [19.00075,4]},
   '19,00085': {$round: [19.00085,4]},
   '19,00095': {$round: [19.00095,4]},
   '19,000005': {$round: [19.000005,5]},
   '19,000015': {$round: [19.000015,5]},
   '19,000025': {$round: [19.000025,5]},
   '19,000035': {$round: [19.000035,5]},
   '19,000045': {$round: [19.000045,5]},
   '19,000055': {$round: [19.000055,5]},
   '19,000065': {$round: [19.000065,5]},
   '19,000075': {$round: [19.000075,5]},
   '19,000085': {$round: [19.000085,5]},
   '19,000095': {$round: [19.000095,5]},
}}]

The following results are returned:

    "1905" : 1900.0,
    "1915" : 1920.0,
    "1925" : 1920.0,
    "1935" : 1940.0,
    "1945" : 1940.0,
    "1955" : 1960.0,
    "1965" : 1960.0,
    "1975" : 1980.0,
    "1985" : 1980.0,
    "1995" : 2000.0,
    "190,5" : 190.0,
    "191,5" : 192.0,
    "192,5" : 192.0,
    "193,5" : 194.0,
    "194,5" : 194.0,
    "195,5" : 196.0,
    "196,5" : 196.0,
    "197,5" : 198.0,
    "198,5" : 198.0,
    "199,5" : 200.0,
    "19,05" : 19.1,
    "19,15" : 19.1,
    "19,25" : 19.2,
    "19,35" : 19.4,
    "19,45" : 19.4,
    "19,55" : 19.6,
    "19,65" : 19.6,
    "19,75" : 19.8,
    "19,85" : 19.9,
    "19,95" : 19.9,
    "19,005" : 19.0,
    "19,015" : 19.02,
    "19,025" : 19.02,
    "19,035" : 19.04,
    "19,045" : 19.05,
    "19,055" : 19.05,
    "19,065" : 19.07,
    "19,075" : 19.07,
    "19,085" : 19.09,
    "19,095" : 19.09,
    "19,0005" : 19.0,
    "19,0015" : 19.002,
    "19,0025" : 19.003,
    "19,0035" : 19.003,
    "19,0045" : 19.005,
    "19,0055" : 19.006,
    "19,0065" : 19.006,
    "19,0075" : 19.008,
    "19,0085" : 19.009,
    "19,0095" : 19.009,
    "19,00005" : 19.0001,
    "19,00015" : 19.0002,
    "19,00025" : 19.0003,
    "19,00035" : 19.0004,
    "19,00045" : 19.0005,
    "19,00055" : 19.0006,
    "19,00065" : 19.0007,
    "19,00075" : 19.0008,
    "19,00085" : 19.0008,
    "19,00095" : 19.0009,
    "19,000005" : 19.00001,
    "19,000015" : 19.00002,
    "19,000025" : 19.00003,
    "19,000035" : 19.00004,
    "19,000045" : 19.00005,
    "19,000055" : 19.00005,
    "19,000065" : 19.00006,
    "19,000075" : 19.00007,
    "19,000085" : 19.00008,
    "19,000095" : 19.0001

As far as I can tell it does not match the described behaviour in the docs when rounding decimal values.
Am I missing something or is there a bug in the behaviour for $round?

Hi @Gerrie_Van_wyk - Welcome to the community

I believe the explanation for the behaviour you are seeing can be described in the following MongoDB ticket SERVER-71557 in which is it working as designed due to how floating point numbers work. If you want more precision, consider using Decimal128 numbers.

Regards,
Jason

1 Like