[erlang-questions] Inf, NaN, and -Inf

Richard O'Keefe <>
Mon Feb 27 22:53:51 CET 2012


On 28/02/2012, at 8:28 AM, Tom Burdick wrote:

> What I actually need, for clarification is...
> 
> minmax({Min, Max}, Values) ->
>     {min(lists:min(Values), Min), max(lists:max(Values), Max)}

Let's do this the efficient way.

min_max([X1,X2|Xs])
  when X1 =< X2 -> min_max(Xs, X1, X2);
min_max([X1,X2|Xs])
  when X1 > X2  -> min_max(Xs, X2, X1);
min_max([X])
  when X =< X -> {X, X}.

min_max({Min,Max}, Values)
  when Min =< Max -> min_max(Values, Min, Max);
min_max({Min,Max}, Values)
  when Min > Max  -> min_max(Values, Max, Min).

min_max([X1,X2|Xs], Min, Max) ->
    if X1 =< X2 ->
       min_max(Xs, if X1 < Min -> X1 ; true -> Min end,
                   if X2 > Max -> X2 ; true -> Max end)
     ; X1 > X2 ->
       min_max(Xs, if X2 < Min -> X2 ; true -> Min end,
		   if X1 > Max -> X1 ; true -> Max end)
    end;
min_max([X], Min, Max) ->
    { if X < Min -> X ; true -> Min end,
      if X > Max -> X ; true -> Max end };
min_max([], Min, Max) ->
    { Min, Max }.

This uses the well known 2-elements-at-a-time hack to do 1.5N
comparisons instead of 2N.

> Except I'd like to be able to set some Min, Max value before ever getting values that still makes sense in javascript as well as erlang and still works with the above situation.

Remember, Javascript doesn't actually do integers, let alone bignums.

> minmax is repeatedly called with a new list of values that are generated from some source like a user supplied CSV file without any known value range, and is far too large to fit entirely in memory.
> 
> I hope this helps to understand the problem. With erlang it appears I'd need a special case now.

No, there is NO, repeat *NO* default initial value you can use
for a foldl loop in ANY language to *correctly* compute minimums
or maximums.  The method I gave above is what you should use in
*any* language.

> 
> In other languages that special case isn't necessary because min and max work with IEEE inf and - inf as expected.

Wrong.  In Haskell, for example, 'minimum []' and 'maximum []' are errors.
In Smalltalk, '#() min' and '#() max' are errors, and there is
no standard way to create ±inf.
In C, of course, there is a standard way to get infinities,
but it is *optional*, and not all C compilers support it, even
on machines with IEEE-compatible hardware.
In languages admitting bignums, you run into serious problems
when a collection contains both floating point numbers and
integers-that-are-outside-the-finite-FP-range.

What we are going to do when people realise that new machines are
coming out with decimal floating point arithmetic (it's part of the
C standard!) and start mixing binary and decimal floats with their
different ranges is keeping me awake some nights.  (Because I'm on
the mailing list for two standard revisions.)

In any case, if you supply a list that was expected to be a list
of integers, and get a floating point infinity back, you are entitled
to be very very upset (especially as floating point infinities are
not the largest values in the Erlang term order, *or* the Prolog one).




More information about the erlang-questions mailing list