Skip to content

Instantly share code, notes, and snippets.

@amaembo
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amaembo/1edf2045b687a0ac9db8 to your computer and use it in GitHub Desktop.
Save amaembo/1edf2045b687a0ac9db8 to your computer and use it in GitHub Desktop.
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.stream.Collector;
final class AverageLong {
long hi, lo, cnt;
public void accept(long val) {
cnt++;
int cmp = Long.compareUnsigned(lo, lo += val);
if (val > 0) {
if (cmp > 0)
hi++;
} else if (cmp < 0)
hi--;
}
public AverageLong combine(AverageLong other) {
cnt += other.cnt;
hi += other.hi;
if (Long.compareUnsigned(lo, lo += other.lo) > 0) {
hi++;
}
return this;
}
public double result() {
if (cnt == 0)
return 0.0d;
if (hi == 0 && lo >= 0 || hi == -1 && lo < 0) {
return ((double) lo) / cnt;
}
return new BigDecimal(new BigInteger(ByteBuffer.allocate(16)
.order(ByteOrder.BIG_ENDIAN).putLong(hi).putLong(lo).array()))
.divide(BigDecimal.valueOf(cnt), MathContext.DECIMAL64)
.doubleValue();
}
static <T> Collector<T, ?, Double> averagingInt(
ToIntFunction<? super T> mapper) {
return Collector.of(AverageLong::new,
(al, n) -> al.accept(mapper.applyAsInt(n)),
AverageLong::combine, AverageLong::result);
}
static <T> Collector<T, ?, Double> averagingLong(
ToLongFunction<? super T> mapper) {
return Collector.of(AverageLong::new,
(al, n) -> al.accept(mapper.applyAsLong(n)),
AverageLong::combine, AverageLong::result);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment