Open Tim-Pohlmann opened 9 months ago
Addition: What about positive+negative? Is that intended to implicitly fall back to "we don't know" scenario?
We should be able to do multiplication for negative*negative too?
Why do the multiplication and division needs to work with constants only, and not positive/negative?
@pavel-mikula-sonarsource Generally speaking, my idea is, "Let's assume that the result is assigned to one of the operands and thus reused in this calculation in later iterations."
What about positive+negative? Is that intended to implicitly fall back to "we don't know" scenario? Yes. We should be able to do multiplication for negative*negative too? This would always be positive. But if it is assigned to one of the two operands, its signage would flip, and future iterations would give different results. Why do the multiplication and division needs to work with constants only, and not positive/negative? I want to avoid cases where the signage would flip. If the second operand is a constant, the result can only be assigned to the left operand, which would not result in a flipped signage.
I want to avoid cases where the signage would flip. If the second operand is a constant, the result can only be assigned to the left operand, which would not result in a flipped signage.
That's the gap I'm asking about. If we do it with number (not constants) and we know if they are positive/negative, we never flip the signage.
We don't, because we don't know what the result will be assigned to:
var negative = -1;
var positive = 5;
while (condition)
{
positive = positive * negative;
}
Follow-up to #8474 Specification
Currently, the SE engine is not conducting any calculations for arithmetic operations in loops. The following assumptions are approximations for calculations in a loop and can be added one by one:
positive + positive
=>[left.Min + right.Min, null]
negative + negative
=>[null, left.Max + right.Max]
(partial implementation exists but does not handle 0)number + positive constant
=>[left.Min + right, null]
number + negative constant
=>[null, left.Max + right]
number + 0 constant
=>[left.Min, left.Max]
number - positive constant
=>[null, left.Max - right]
number - negative constant
=>[left.Min - right, null]
number - 0 constant
=>[left.Min, left.Max]
number * 0
=>[0, 0]
positive * positive
=>[left.Min * right.Min, null]
negative * positive constant
=>[null, left.Max * right]
positive / positive constant
=>[0, left.Max / right]
negative / positive constant
=>[left.Min / right, 0]
number / positive constant
=>[-left.Min / right, left.Max / right]
number / negative constant
=>[Max(|left.Min|, |left.Max|) / right, Max(|left.Min|, |left.Max|) / -right]
number % constant
=> same logic as outside a loopnumber & number
=> same logic as outside a loopnumber | number
=> same logic as outside a loopnumber ^ 0 constant
=>[left.Min, left.Max]
positive ^ positive
=>[0, null]
negative ^ positive constant
=>[null, -1]