public static double Max(double val1, double val2)
{
- // When val1 and val2 are both finite or infinite, return the larger
- // * We count +0.0 as larger than -0.0 to match MSVC
- // When val1 or val2, but not both, are NaN return the opposite
- // * We return the opposite if either is NaN to match MSVC
+ // This matches the IEEE 754:2019 `maximum` function
+ //
+ // It propagates NaN inputs back to the caller and
+ // otherwise returns the larger of the inputs. It
+ // treats +0 as larger than -0 as per the specification.
- if (double.IsNaN(val1))
- {
- return val2;
- }
-
- if (double.IsNaN(val2))
+ if ((val1 > val2) || double.IsNaN(val1))
{
return val1;
}
- // We do this comparison first and separately to handle the -0.0 to +0.0 comparision
- // * Doing (val1 < val2) first could get transformed into (val2 >= val1) by the JIT
- // which would then return an incorrect value
-
if (val1 == val2)
{
return double.IsNegative(val1) ? val2 : val1;
}
- return (val1 < val2) ? val2 : val1;
+ return val2;
}
[NonVersionable]
public static float Max(float val1, float val2)
{
- // When val1 and val2 are both finite or infinite, return the larger
- // * We count +0.0 as larger than -0.0 to match MSVC
- // When val1 or val2, but not both, are NaN return the opposite
- // * We return the opposite if either is NaN to match MSVC
+ // This matches the IEEE 754:2019 `maximum` function
+ //
+ // It propagates NaN inputs back to the caller and
+ // otherwise returns the larger of the inputs. It
+ // treats +0 as larger than -0 as per the specification.
- if (float.IsNaN(val1))
- {
- return val2;
- }
-
- if (float.IsNaN(val2))
+ if ((val1 > val2) || float.IsNaN(val1))
{
return val1;
}
- // We do this comparison first and separately to handle the -0.0 to +0.0 comparision
- // * Doing (val1 < val2) first could get transformed into (val2 >= val1) by the JIT
- // which would then return an incorrect value
-
if (val1 == val2)
{
return float.IsNegative(val1) ? val2 : val1;
}
- return (val1 < val2) ? val2 : val1;
+ return val2;
}
[CLSCompliant(false)]
public static double MaxMagnitude(double x, double y)
{
- // When x and y are both finite or infinite, return the larger magnitude
- // * We count +0.0 as larger than -0.0 to match MSVC
- // When x or y, but not both, are NaN return the opposite
- // * We return the opposite if either is NaN to match MSVC
+ // This matches the IEEE 754:2019 `maximumMagnitude` function
+ //
+ // It propagates NaN inputs back to the caller and
+ // otherwise returns the input with a larger magnitude.
+ // It treats +0 as larger than -0 as per the specification.
- if (double.IsNaN(x))
- {
- return y;
- }
+ double ax = Abs(x);
+ double ay = Abs(y);
- if (double.IsNaN(y))
+ if ((ax > ay) || double.IsNaN(ax))
{
return x;
}
- // We do this comparison first and separately to handle the -0.0 to +0.0 comparision
- // * Doing (ax < ay) first could get transformed into (ay >= ax) by the JIT which would
- // then return an incorrect value
-
- double ax = Abs(x);
- double ay = Abs(y);
-
if (ax == ay)
{
return double.IsNegative(x) ? y : x;
}
- return (ax < ay) ? y : x;
+ return y;
}
[NonVersionable]
public static double Min(double val1, double val2)
{
- // When val1 and val2 are both finite or infinite, return the smaller
- // * We count -0.0 as smaller than -0.0 to match MSVC
- // When val1 or val2, but not both, are NaN return the opposite
- // * We return the opposite if either is NaN to match MSVC
+ // This matches the IEEE 754:2019 `minimum` function
+ //
+ // It propagates NaN inputs back to the caller and
+ // otherwise returns the larger of the inputs. It
+ // treats +0 as larger than -0 as per the specification.
- if (double.IsNaN(val1))
- {
- return val2;
- }
-
- if (double.IsNaN(val2))
+ if ((val1 < val2) || double.IsNaN(val1))
{
return val1;
}
- // We do this comparison first and separately to handle the -0.0 to +0.0 comparision
- // * Doing (val1 < val2) first could get transformed into (val2 >= val1) by the JIT
- // which would then return an incorrect value
-
if (val1 == val2)
{
return double.IsNegative(val1) ? val1 : val2;
}
- return (val1 < val2) ? val1 : val2;
+ return val2;
}
[NonVersionable]
public static float Min(float val1, float val2)
{
- // When val1 and val2 are both finite or infinite, return the smaller
- // * We count -0.0 as smaller than -0.0 to match MSVC
- // When val1 or val2, but not both, are NaN return the opposite
- // * We return the opposite if either is NaN to match MSVC
+ // This matches the IEEE 754:2019 `minimum` function
+ //
+ // It propagates NaN inputs back to the caller and
+ // otherwise returns the larger of the inputs. It
+ // treats +0 as larger than -0 as per the specification.
- if (float.IsNaN(val1))
- {
- return val2;
- }
-
- if (float.IsNaN(val2))
+ if ((val1 < val2) || float.IsNaN(val1))
{
return val1;
}
- // We do this comparison first and separately to handle the -0.0 to +0.0 comparision
- // * Doing (val1 < val2) first could get transformed into (val2 >= val1) by the JIT
- // which would then return an incorrect value
-
if (val1 == val2)
{
return float.IsNegative(val1) ? val1 : val2;
}
- return (val1 < val2) ? val1 : val2;
+ return val2;
}
[CLSCompliant(false)]
public static double MinMagnitude(double x, double y)
{
- // When x and y are both finite or infinite, return the smaller magnitude
- // * We count -0.0 as smaller than -0.0 to match MSVC
- // When x or y, but not both, are NaN return the opposite
- // * We return the opposite if either is NaN to match MSVC
+ // This matches the IEEE 754:2019 `minimumMagnitude` function
+ //
+ // It propagates NaN inputs back to the caller and
+ // otherwise returns the input with a larger magnitude.
+ // It treats +0 as larger than -0 as per the specification.
- if (double.IsNaN(x))
- {
- return y;
- }
+ double ax = Abs(x);
+ double ay = Abs(y);
- if (double.IsNaN(y))
+ if ((ax < ay) || double.IsNaN(ax))
{
return x;
}
- // We do this comparison first and separately to handle the -0.0 to +0.0 comparision
- // * Doing (ax < ay) first could get transformed into (ay >= ax) by the JIT which would
- // then return an incorrect value
-
- double ax = Abs(x);
- double ay = Abs(y);
-
if (ax == ay)
{
return double.IsNegative(x) ? x : y;
}
- return (ax < ay) ? x : y;
+ return y;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float MaxMagnitude(float x, float y)
{
- // When x and y are both finite or infinite, return the larger magnitude
- // * We count +0.0 as larger than -0.0 to match MSVC
- // When x or y, but not both, are NaN return the opposite
- // * We return the opposite if either is NaN to match MSVC
+ // This matches the IEEE 754:2019 `maximumMagnitude` function
+ //
+ // It propagates NaN inputs back to the caller and
+ // otherwise returns the input with a larger magnitude.
+ // It treats +0 as larger than -0 as per the specification.
- if (float.IsNaN(x))
- {
- return y;
- }
+ float ax = Abs(x);
+ float ay = Abs(y);
- if (float.IsNaN(y))
+ if ((ax > ay) || float.IsNaN(ax))
{
return x;
}
- // We do this comparison first and separately to handle the -0.0 to +0.0 comparision
- // * Doing (ax < ay) first could get transformed into (ay >= ax) by the JIT which would
- // then return an incorrect value
-
- float ax = Abs(x);
- float ay = Abs(y);
-
if (ax == ay)
{
return float.IsNegative(x) ? y : x;
}
- return (ax < ay) ? y : x;
+ return y;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float MinMagnitude(float x, float y)
{
- // When x and y are both finite or infinite, return the smaller magnitude
- // * We count -0.0 as smaller than -0.0 to match MSVC
- // When x or y, but not both, are NaN return the opposite
- // * We return the opposite if either is NaN to match MSVC
+ // This matches the IEEE 754:2019 `minimumMagnitude` function
+ //
+ // It propagates NaN inputs back to the caller and
+ // otherwise returns the input with a larger magnitude.
+ // It treats +0 as larger than -0 as per the specification.
- if (float.IsNaN(x))
- {
- return y;
- }
+ float ax = Abs(x);
+ float ay = Abs(y);
- if (float.IsNaN(y))
+ if ((ax < ay) || float.IsNaN(ax))
{
return x;
}
- // We do this comparison first and separately to handle the -0.0 to +0.0 comparision
- // * Doing (ax < ay) first could get transformed into (ay >= ax) by the JIT which would
- // then return an incorrect value
-
- float ax = Abs(x);
- float ay = Abs(y);
-
if (ax == ay)
{
return float.IsNegative(x) ? x : y;
}
- return (ax < ay) ? x : y;
+ return y;
}
[Intrinsic]