Skip to content

Commit

Permalink
[release/8.0] Fix NaN handling (#4365)
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] authored Sep 7, 2023
1 parent 9ad2b7e commit e464d05
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ public static Utilization CalculateUtilization(in ResourceUtilizationSnapshot fi
// Compute the total number of ticks available on the machine during that interval
double totalSystemTicks = runtimeTickDelta * systemResources.GuaranteedCpuUnits;

// fudge to avoid divide by zero
if (totalSystemTicks <= 0)
{
totalSystemTicks = 1;
}

// Now, compute the amount of usage between the intervals
long oldUsageTicks = first.KernelTimeSinceStart.Ticks + first.UserTimeSinceStart.Ticks;
long newUsageTicks = second.KernelTimeSinceStart.Ticks + second.UserTimeSinceStart.Ticks;
Expand Down
25 changes: 19 additions & 6 deletions src/Shared/Throw/Throw.cs
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,10 @@ public static ulong IfZero(ulong argument, [CallerArgumentExpression(nameof(argu
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double IfLessThan(double argument, double min, [CallerArgumentExpression(nameof(argument))] string paramName = "")
{
if (argument < min)
// strange conditional needed in order to handle NaN values correctly
#pragma warning disable S1940 // Boolean checks should not be inverted
if (!(argument >= min))
#pragma warning restore S1940 // Boolean checks should not be inverted
{
ArgumentOutOfRangeException(paramName, argument, $"Argument less than minimum value {min}");
}
Expand All @@ -888,7 +891,10 @@ public static double IfLessThan(double argument, double min, [CallerArgumentExpr
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double IfGreaterThan(double argument, double max, [CallerArgumentExpression(nameof(argument))] string paramName = "")
{
if (argument > max)
// strange conditional needed in order to handle NaN values correctly
#pragma warning disable S1940 // Boolean checks should not be inverted
if (!(argument <= max))
#pragma warning restore S1940 // Boolean checks should not be inverted
{
ArgumentOutOfRangeException(paramName, argument, $"Argument greater than maximum value {max}");
}
Expand All @@ -906,7 +912,10 @@ public static double IfGreaterThan(double argument, double max, [CallerArgumentE
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double IfLessThanOrEqual(double argument, double min, [CallerArgumentExpression(nameof(argument))] string paramName = "")
{
if (argument <= min)
// strange conditional needed in order to handle NaN values correctly
#pragma warning disable S1940 // Boolean checks should not be inverted
if (!(argument > min))
#pragma warning restore S1940 // Boolean checks should not be inverted
{
ArgumentOutOfRangeException(paramName, argument, $"Argument less or equal than minimum value {min}");
}
Expand All @@ -924,7 +933,10 @@ public static double IfLessThanOrEqual(double argument, double min, [CallerArgum
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double IfGreaterThanOrEqual(double argument, double max, [CallerArgumentExpression(nameof(argument))] string paramName = "")
{
if (argument >= max)
// strange conditional needed in order to handle NaN values correctly
#pragma warning disable S1940 // Boolean checks should not be inverted
if (!(argument < max))
#pragma warning restore S1940 // Boolean checks should not be inverted
{
ArgumentOutOfRangeException(paramName, argument, $"Argument greater or equal than maximum value {max}");
}
Expand All @@ -943,7 +955,8 @@ public static double IfGreaterThanOrEqual(double argument, double max, [CallerAr
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double IfOutOfRange(double argument, double min, double max, [CallerArgumentExpression(nameof(argument))] string paramName = "")
{
if (argument < min || argument > max)
// strange conditional needed in order to handle NaN values correctly
if (!(min <= argument && argument <= max))
{
ArgumentOutOfRangeException(paramName, argument, $"Argument not in the range [{min}..{max}]");
}
Expand All @@ -961,7 +974,7 @@ public static double IfOutOfRange(double argument, double min, double max, [Call
public static double IfZero(double argument, [CallerArgumentExpression(nameof(argument))] string paramName = "")
{
#pragma warning disable S1244 // Floating point numbers should not be tested for equality
if (Math.Abs(argument) == 0.0)
if (argument == 0.0)
#pragma warning restore S1244 // Floating point numbers should not be tested for equality
{
ArgumentOutOfRangeException(paramName, "Argument is zero");
Expand Down
23 changes: 22 additions & 1 deletion test/Shared/Throw/DoubleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public void IfDoubleLessThan_ThrowWhenLessThan()
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfLessThan(0.0, 1.0, "paramName"));
Assert.Equal("paramName", exception.ParamName);
Assert.StartsWith("Argument less than minimum value 1", exception.Message);

exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfLessThan(double.NaN, 1.0, "paramName"));
Assert.Equal("paramName", exception.ParamName);
Assert.StartsWith("Argument less than minimum value 1", exception.Message);
}

[Fact]
Expand All @@ -33,6 +37,10 @@ public void IfDoubleGreaterThan_ThrowWhenGreaterThan()
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfGreaterThan(1.4, 0.0, "paramName"));
Assert.Equal("paramName", exception.ParamName);
Assert.StartsWith("Argument greater than maximum value 0", exception.Message);

exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfGreaterThan(double.NaN, 0.0, "paramName"));
Assert.Equal("paramName", exception.ParamName);
Assert.StartsWith("Argument greater than maximum value 0", exception.Message);
}

[Fact]
Expand All @@ -48,6 +56,10 @@ public void IfDoubleLessThanOrEqual_ThrowWhenEqual()
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfLessThanOrEqual(1.2, 1.2, "paramName"));
Assert.Equal("paramName", exception.ParamName);
Assert.StartsWith("Argument less or equal than minimum value 1.2", exception.Message);

exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfLessThanOrEqual(double.NaN, 1.2, "paramName"));
Assert.Equal("paramName", exception.ParamName);
Assert.StartsWith("Argument less or equal than minimum value 1.2", exception.Message);
}

[Fact]
Expand All @@ -63,6 +75,10 @@ public void IfDoubleGreaterThanOrEqual_ThrowWhenEqual()
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfGreaterThanOrEqual(1.22, 1.22, "paramName"));
Assert.Equal("paramName", exception.ParamName);
Assert.StartsWith("Argument greater or equal than maximum value 1.22", exception.Message);

exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfGreaterThanOrEqual(double.NaN, 1.22, "paramName"));
Assert.Equal("paramName", exception.ParamName);
Assert.StartsWith("Argument greater or equal than maximum value 1.22", exception.Message);
}

[Fact]
Expand All @@ -86,14 +102,15 @@ public void IfDoubleZero_ThrowWhenZero(double zero)
[InlineData(0.001)]
[InlineData(-0.010)]
[InlineData(1.1)]
[InlineData(double.NaN)]
public void IfDoubleZero_DoesntThrow_WhenNotZero(double notZero)
{
var exception = Record.Exception(() => Throw.IfZero(notZero, "paramName"));
Assert.Null(exception);
}

[Fact]
public void Double_OUtOfRange()
public void Double_OutOfRange()
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfOutOfRange(-1.0, 0, 1, "foo"));
Assert.Equal("foo", exception.ParamName);
Expand All @@ -105,6 +122,10 @@ public void Double_OUtOfRange()

Assert.Equal(0, Throw.IfOutOfRange(0.0, 0, 1, "foo"));
Assert.Equal(1, Throw.IfOutOfRange(1.0, 0, 1, "foo"));

exception = Assert.Throws<ArgumentOutOfRangeException>(() => Throw.IfOutOfRange(double.NaN, 0, 1, "foo"));
Assert.Equal("foo", exception.ParamName);
Assert.StartsWith("Argument not in the range", exception.Message);
}

[Fact]
Expand Down

0 comments on commit e464d05

Please sign in to comment.