Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SE: Add RemainderOperation #7263

Merged
merged 7 commits into from
May 31, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor
  • Loading branch information
Tim-Pohlmann committed May 26, 2023
commit eecb5cab48c88b5b6aef4ca4505832dd4c4f07b2
Original file line number Diff line number Diff line change
Expand Up @@ -144,48 +144,50 @@ private static NumberConstraint CalculateRemainder(NumberConstraint left, Number

private static BigInteger? CalculateRemainderMin(NumberConstraint left, NumberConstraint right)
{
if (left.IsPositive)
// If every divisor is absolutely bigger than any dividend => resulting range == dividend range.
// Otherwise, the result is bigger or equals 0 for positive dividend values and absolutely bigger than the divisor for negative dividend values.
if (left.CanBeNegative || left.Max < MinOfAbsoluteValues(right))
{
// Assuming both ranges are positive and every possible divisor value is > every possible dividend value => resulting range == dividend range.
// The sign of the divisor has no impact on the result => For negative or mixed divisor, we can take its absolute value and apply the same logic as above.
return left.Max is null || left.Max >= MinOfAbsoluteValues(right) ? 0 : left.Min;
}
else
{
var minDerivedFromRight = -MaxOfAbsoluteValues(right) + 1;
if (minDerivedFromRight is null)
if (right.Min is null || right.Max is null)
{
// If righ is not finite, there will always be a divisor which is absolutely bigger than any value in left => resulting range == dividend range.
// If right is not finite, there will always be a divisor which is absolutely bigger than any value in left => resulting range == dividend range.
return left.Min;
}
else
{
return left.Min is null ? minDerivedFromRight : BigInteger.Max(left.Min.Value, minDerivedFromRight.Value);
// The result cannot be absolutely bigger than the absolute divisor - 1. For negative dividends the inverse is true.
var minDerivedFromRight = -MaxOfAbsoluteValues(right).Value + 1;
return left.Min is null ? minDerivedFromRight : BigInteger.Max(left.Min.Value, minDerivedFromRight);
}
}
else
{
return 0;
}
}

private static BigInteger? CalculateRemainderMax(NumberConstraint left, NumberConstraint right)
{
if (left.IsNegative)
// If every divisor is absolutely bigger than any dividend => resulting range == dividend range.
// Otherwise, the result is smaller or equals 0 for negative dividend values and absolutely smaller than the divisor for positive dividend values.
if (left.CanBePositive || -left.Max < MinOfAbsoluteValues(right))
{
// Assuming both ranges are negative and every possible divisor value is < every possible dividend value => resulting range == dividend range.
// The sign of the divisor has no impact on the result => For positive or mixed divisor, we can take its absolute value and apply the same logic as above.
return left.Max <= -MinOfAbsoluteValues(right) ? 0 : left.Max;
}
else
{
var maxDerivedFromRight = MaxOfAbsoluteValues(right) - 1;
if (maxDerivedFromRight is null)
if (right.Min is null || right.Max is null)
{
// If righ is not finite, there will always be a divisor which is absolutely bigger than any value in left => resulting range == dividend range.
// If right is not finite, there will always be a divisor which is absolutely bigger than any value in left => resulting range == dividend range.
return left.Max;
}
else
{
// The result cannot be absolutely bigger than the absolute divisor - 1.
var maxDerivedFromRight = MaxOfAbsoluteValues(right) - 1;
return left.Max is null ? maxDerivedFromRight : BigInteger.Min(left.Max.Value, maxDerivedFromRight.Value);
}
}
else
{
return 0;
}
}

private static NumberConstraint AccountForZero(NumberConstraint constraint)
Expand Down