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

Math.sum? #4

Open
ljharb opened this issue Sep 1, 2016 · 14 comments
Open

Math.sum? #4

ljharb opened this issue Sep 1, 2016 · 14 comments

Comments

@ljharb
Copy link

ljharb commented Sep 1, 2016

Simplifying things like Math.sum(...Object.values(x)) or Math.sum(...numbers) where previously we'd need .reduce((a, b) => a+ b)?

@rwaldron
Copy link
Owner

rwaldron commented Sep 1, 2016

Since we're "pivoting" this proposal to be a broader Math update, I think this addition is solid.

@ghost
Copy link

ghost commented Oct 31, 2016

If Math.sum makes it, Math.product might be useful, too.

@kevinbarabash
Copy link

Here's an attempt at being more specific:

  • If any argument is NaN the result should be NaN. This can be used to bail out early.
  • Otherwise:
    • If any argument is Infinity and no other arguments are -Infinity the result is Infinity
    • If any argument is -Infinity and no other arguments are Infinity the result is -Infinity
    • If any argument is Infinity and any other argument is -Infinity the result is NaN
    • If typeof arg !== 'number' for any argument the result is NaN. Overloading Math functions to work on strings should not be allow.
    • Otherwise the result is the sum of the arguments computed by adding them in order.
      • If no arguments are provided, the result is 0.

Here's a possible implementation:

Math.sum = (...args) => {
   let result = 0;
   for (let i = 0; i < args.length; i++) {
      if (typeof args[i] !== 'number') {
          return NaN;
      }
      result += args[i];
      if (isNaN(result)) {
          return result;
      }
   }
   return result;
};

@ljharb
Copy link
Author

ljharb commented Feb 4, 2017

Actually I think all arguments should be coerced ToNumber, like almost all builtin Math methods. In other words, it should definitely work on strings.

@ljharb
Copy link
Author

ljharb commented Feb 4, 2017

Effectively, Math.sum = function sum(...args) { return args.reduce((a, b) => Number(a) + Number(b), 0); }' - I would be quite surprised if that polyfill did not match the spec.

@kevinbarabash
Copy link

TIL that Math methods coerce strings to numbers.

@petamoriken
Copy link

Why don't you adopt Kahan summation algorithm?
https://en.wikipedia.org/wiki/Kahan_summation_algorithm

@ljharb
Copy link
Author

ljharb commented Jul 12, 2017

That sounds like a specific implementation, which the spec usually does not dictate. That's the sort of thing that if it is not observable, an implementation is free to use.

@petamoriken
Copy link

@ljharb Kahan summation algorithm is a compensated summation (observable).

// Naive summation
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7].reduce(function(a, b) { return a + b })
// -> 15.299999999999999

// Kahan summation
require('kahan').sum([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7])
// -> 15.3

https://github.com/viktors/node-kahan

Stream API (Collection) in Java use this algorithm.
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/stream/Collectors.java#l538

@micnic
Copy link

micnic commented Apr 16, 2018

@petamoriken Python has Math.fsum() for accurate floating point sum.

Maybe add both? 😄 Math.sum() - fast implementation and Math.fsum() - slower implementation, but more accurate

@MaxGraey
Copy link

MaxGraey commented Mar 4, 2019

I vote for single accurate Math.sum() which probably could use iterative pairwise summation like in Julia or Shewchuk's algorithm like in Python, but not Kahan summation which not always guarantee accurate results.

@petamoriken
Copy link

That's going to be a different proposal
https://github.com/bakkot/proposal-math-sum

@Rudxain
Copy link

Rudxain commented Dec 3, 2023

I agree with @ljharb, the algorithm should be implementation-defined. The only requirement the spec should impose, is to make the sum as accurate/precise as possible (by minimizing rounding-errors). This can be accomplished with summation-algorithms designed for F.P.-arithmetic, or by internally using BigFloats

@ljharb
Copy link
Author

ljharb commented Dec 3, 2023

To be clear; the spec will need to include some algorithm. It’s just that it should be possible for implementations to choose another one that’s observably the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants