Live data from Hacker News

Calculating the mean of a list of numbers (2016)

hypothesis.works

11–20 of 96 posts

Re: Calculating the mean of a list of numbers (2016)

#11
post #4

This article highlights and issue with floating point numbers, a substantial use case for data scientists (and as such, I value the input). How do REPLs and databases handle this edge case?

If you when calculating an average actually reach overflow in a double without messing up the precision first and making the calculation worthless in the first place, some numbers in the list of numbers is bogusly big anyway.

Re: Calculating the mean of a list of numbers (2016)

#13
post #4

This article highlights and issue with floating point numbers, a substantial use case for data scientists (and as such, I value the input). How do REPLs and databases handle this edge case?

One option is to convert to a bignum representation, which is slow but works.

Re: Calculating the mean of a list of numbers (2016)

#14
post #4

This article highlights and issue with floating point numbers, a substantial use case for data scientists (and as such, I value the input). How do REPLs and databases handle this edge case?

If you when calculating an average actually reach overflow in a double without messing up the precision first and making the calculation worthless in the first place, some numbers in the list of numbers is bogusly big anyway.

Or the list is just very long.

Re: Calculating the mean of a list of numbers (2016)

#15

  This is the TXR Lisp interactive listener of TXR 214.
  Quit with :quit or Ctrl-D on empty line. Ctrl-X ? for cheatsheet.
  1> (defun mean (seq) (/ (sum seq) (len seq)))
  mean
  2> (mean '(8.988465674311579e+307 8.98846567431158e+307))
  ** out-of-range floating-point result
  ** during evaluation at expr-1:1 of form (sum seq)
Works for me; error is caught. Breaking news: floating-point has a limited range! Detailed story at 11 ...

Almost any non-trivial calculation that overflows can be massaged into something that avoids overflow. One important motivation behind floating point is to have enough practical range so that you don't run into overflow.

If this is an actual practical problem someone faces, the tool to reach for is wider floating-point, not to mess with the code. A bigger "E" than +307 is a thing.

Also, multi-precision floating-point is a thing.

Re: Calculating the mean of a list of numbers (2016)

#19
In ruby you need to use bigdecimal:

    precision = Float::DIG + 1
    require 'bigdecimal'
    a = BigDecimal(8.98846567431158e+307, precision)
    b = BigDecimal(8.988465674311579e+307, precision)
    mean = (a + b) / 2
    puts "Works" if mean > [a, b].min && mean  Works
(edit: I used 0 first and it works fine but converts to precision 15 instead of 16 (which is the maximum on my computer) for some reason, I may file a bug for this)

Works for small floats too:

    smalls = [1.390671161567e-309, 1.390671161567e-309, 1.390671161567e-309].map { BigDecimal(@1, precision) }
    mean = smalls.sum / smalls.size
    puts "Works" if mean >= smalls.min && mean  Works
One could also use BigDecimal("8.98846567431158e+307") but seems like the numbers are coming as floats.

Re: Calculating the mean of a list of numbers (2016)

#20
post #2

An interesting article describing a useful framework. In addition to the largest numbers that floating point can handle, a related issue can come up with numbers that are not near the edge. A good student of floating point numbers will notice that there is a good chance you will get a different result summing a list of floating point numbers if they are sorted in a different order. This is due to the rounding error t…

It's amazing how many floating point edge cases emerge from mid-range values. Ordering can also help minimize the accumulation of rounding errors for similar reasons to those you pointed out.
Post reply on HN