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

Precision issue when sum array #333

Open
jerrybyte opened this issue Mar 12, 2024 · 7 comments
Open

Precision issue when sum array #333

jerrybyte opened this issue Mar 12, 2024 · 7 comments
Labels
support Users asking how to solve a specific issue

Comments

@jerrybyte
Copy link

jerrybyte commented Mar 12, 2024

we want to sum the array, but when we used sum() function, it give a wrong result.

Expression : "roundnum" : sum([150.40, 140.51]),
Result: "roundnum" : 290.90999999999997,

@larsga larsga added the support Users asking how to solve a specific issue label Mar 12, 2024
@larsga
Copy link
Collaborator

larsga commented Mar 12, 2024

I'm afraid this is just the nasty nature of floats. Here's what happens if you do the same thing in Python:

Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 19 2020, 20:48:48)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 150.40 + 140.51
290.90999999999997

@catull
Copy link

catull commented Mar 12, 2024

If you want precision, you have to adapt your processing a little.

With this input

{
  "data": [
    150.40,
    140.51
  ]
}

you can apply this transformation:

{
  "roundnum": floor (sum (.data) * 100 + 0.5) / 100
}

The result is:

{
  "roundnum" : 290.91
}

@catull
Copy link

catull commented Mar 12, 2024

Try this, to see the changes applied:

{
  "round1": sum (.data),
  "round2": floor (sum (.data) * 100) / 100,
  "roundnum": floor (sum (.data) * 100 + 0.5) / 100
}

It gives you:

{
  "round1" : 290.90999999999997,
  "round2" : 290.9,
  "roundnum" : 290.91
}

@jerrybyte
Copy link
Author

I'm afraid this is just the nasty nature of floats. Here's what happens if you do the same thing in Python:

Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 19 2020, 20:48:48)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 150.40 + 140.51
290.90999999999997

do we have a decimal type to avoid the precision issue ?

@jerrybyte
Copy link
Author

Try this, to see the changes applied:

{
  "round1": sum (.data),
  "round2": floor (sum (.data) * 100) / 100,
  "roundnum": floor (sum (.data) * 100 + 0.5) / 100
}

It gives you:

{
  "round1" : 290.90999999999997,
  "round2" : 290.9,
  "roundnum" : 290.91
}

' + 0.5 ' is only valid for the current nunmber... if I change the number, it will not work

@catull
Copy link

catull commented Mar 14, 2024

Actually, it is correct for positive sums. @jerrybyte

Try this:

Input:

{
  "data": [
    [
      150.40,
      140.51
    ],
    [
      150.40,
      140.51,
      10.32
    ],
    [
      150.40,
      140.51,
      10.32,
      15.83
    ]
  ]
}

With this transformation:

def calculate (a) {
  let sum = sum ($a)
  "sum": $sum,
  "sumWith2Digits": floor ($sum * 100) / 100,
  "sumRoundedTo2Digits": floor ($sum * 100 + 0.5) / 100
}

[ for (.data)
  calculate (.)
]

The result is:

[ {
  "sum" : 290.90999999999997,
  "sumWith2Digits" : 290.9,
  "sumRoundedTo2Digits" : 290.91
}, {
  "sum" : 301.22999999999996,
  "sumWith2Digits" : 301.22,
  "sumRoundedTo2Digits" : 301.23
}, {
  "sum" : 317.05999999999995,
  "sumWith2Digits" : 317.05,
  "sumRoundedTo2Digits" : 317.06
} ]

@larsga
Copy link
Collaborator

larsga commented Mar 14, 2024

do we have a decimal type to avoid the precision issue ?

What precision are you looking for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support Users asking how to solve a specific issue
Projects
None yet
Development

No branches or pull requests

3 participants