Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does comparing to Math.Min or Math.Max short-circuit?

When comparing to a minimum or maximum of two numbers/functions, does C# short-circuit if the case is true for the first one and would imply truth for the second? Specific examples of these cases are

if(x < Math.Max(y, z()))

and

if(x > Math.Min(y, z()))

Since Math.Max(y, z()) will return a value at least as large as y, if x < y then there is no need to evaluate z(), which could take a while. Similar situation with Math.Min.

I realize that these could both be rewritten along the lines of

if(x < y || x < z())

in order to short-circuit, but I think it's more clear what the comparison is without rewriting. Does this short-circuit?

like image 258
yoozer8 Avatar asked Jan 18 '12 19:01

yoozer8


People also ask

What is the difference between math MIN () and math MAX () functions?

when you execute Math. min(), you will get (Infinity) and when you execute Math. max(), you will get (-Infinity).

Why is math MAX () less than math MIN ()?

max() starts with a search value of -Infinity , because any other number is going to be greater than -Infinity. Similarly, Math. min() starts with the search value of Infinity : “If no arguments are given, the result is Infinity .

Is math min slow?

Using Math. Min in a loop is almost 4 times slower than before.

What does math min do in C#?

In C#, Min() is a Math class method which returns the smaller of the two specified numbers. This method always takes two arguments and it can be overloaded by changing the data type of the passed arguments as follows: Math. Min(Byte, Byte): Returns the smaller of the two 8-bit unsigned integers.


1 Answers

As others have pointed out, the compiler knows nothing about the semantics of Min or Max that would allow it to break the rule that arguments are evaluated before the method is called.

If you wanted to write your own, you could do so easily enough:

static bool LazyLessThan(int x, int y, Func<int> z)
{
    return x < y || x < z();
}

and then call it

if (LazyLessThan(x, y, z))

or

if (LazyLessThan(x, y, ()=>z()))

Or for that matter:

static bool LazyRelation<T>(T x, T y, Func<T> z, Func<T, T, bool> relation)
{
    return relation(x, y) || relation(x, z());
}
...
if (LazyRelation(x, y, ()=>z, (a,b)=> a < b))) 
like image 144
Eric Lippert Avatar answered Oct 25 '22 14:10

Eric Lippert