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 · 11 comments

Comments

Projects
None yet
7 participants
@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

This comment has been minimized.

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.

@kdex

This comment has been minimized.

Copy link

kdex commented Oct 31, 2016

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

@kevinbarabash

This comment has been minimized.

Copy link

kevinbarabash commented Feb 4, 2017

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

kevinbarabash commented Feb 4, 2017

TIL that Math methods coerce strings to numbers.

@petamoriken

This comment has been minimized.

Copy link

petamoriken commented Jul 12, 2017

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

@ljharb

This comment has been minimized.

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

This comment has been minimized.

Copy link

petamoriken commented Jul 13, 2017

@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

This comment has been minimized.

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

This comment has been minimized.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.