Open ljharb opened 8 years ago
Since we're "pivoting" this proposal to be a broader Math update, I think this addition is solid.
If Math.sum
makes it, Math.product
might be useful, too.
Here's an attempt at being more specific:
NaN
the result should be NaN
. This can be used to bail out early.Infinity
and no other arguments are -Infinity
the result is Infinity
-Infinity
and no other arguments are Infinity
the result is -Infinity
Infinity
and any other argument is -Infinity
the result is NaN
typeof arg !== 'number'
for any argument the result is NaN
. Overloading Math
functions to work on strings should not be allow.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;
};
Actually I think all arguments should be coerced ToNumber, like almost all builtin Math methods. In other words, it should definitely work on strings.
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.
TIL that Math
methods coerce strings to numbers.
Why don't you adopt Kahan summation algorithm? https://en.wikipedia.org/wiki/Kahan_summation_algorithm
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.
@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
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
@petamoriken Python has Math.fsum()
for accurate floating point sum.
Maybe add both? :smile: Math.sum()
- fast implementation and Math.fsum()
- slower implementation, but more accurate
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.
That's going to be a different proposal https://github.com/bakkot/proposal-math-sum
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 BigFloat
s
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.
Simplifying things like
Math.sum(...Object.values(x))
orMath.sum(...numbers)
where previously we'd need.reduce((a, b) => a+ b)
?