The code is correct from a realistic point of view but implements a stricter criterion than actually stated. Consider e.g.:
2147483647 + 2147483647 + (-2147483648) + (-2147483648)
Here, the result could be a "solid" -2 but CanAdd rejects it nevertheless. As such, the code does not satisfy its requirements (but, in this case, I'd almost certainly adjust the requirements instead of the code ;-).
On a more practical note: simply performing each addition (regardless of overflows), followed by a check if the sign of the result is as expected could marginally improve performance (it suffices to check that at least one argument has the same sign as that of the result, which can be done using trivial bit-wise operations - e.g. (a ^ c) & (b ^ c) >= 0
, where a
and b
are the arguments and c
is the result).
PS: if (and that's a big if) the code may not yield false negatives even in cases such as in the "-2" example, it'd be better to keep track of the difference d
between the number of overflows (positive → negative) and the number of underflows (negative → positive), e.g. by if ((a ^ c) & (b ^ c) < 0) d += c < 0 ? -1 : 1;
. CanAdd should then return d == 0
.
The code is correct from a realistic point of view but implements a stricter criterion than actually stated. Consider e.g.:
2147483647 + 2147483647 + (-2147483648) + (-2147483648)
Here, the result could be a "solid" -2 but CanAdd rejects it nevertheless. As such, the code does not satisfy its requirements (but, in this case, I'd almost certainly adjust the requirements instead of the code ;-).
On a more practical note: simply performing each addition (regardless of overflows), followed by a check if the sign of the result is as expected could marginally improve performance (it suffices to check that at least one argument has the same sign as that of the result, which can be done using trivial bit-wise operations - e.g. (a ^ c) & (b ^ c) >= 0
, where a
and b
are the arguments and c
is the result).
PS: if (and that's a big if) the code may not yield false negatives even in cases such as in the "-2" example, it'd be better to keep track of the difference d
between the number of overflows (positive → negative) and the number of underflows (negative → positive). CanAdd should then return d == 0
.
The code is correct from a realistic point of view but implements a stricter criterion than actually stated. Consider e.g.:
2147483647 + 2147483647 + (-2147483648) + (-2147483648)
Here, the result could be a "solid" -2 but CanAdd rejects it nevertheless. As such, the code does not satisfy its requirements (but, in this case, I'd almost certainly adjust the requirements instead of the code ;-).
On a more practical note: simply performing each addition (regardless of overflows), followed by a check if the sign of the result is as expected could marginally improve performance (it suffices to check that at least one argument has the same sign as that of the result, which can be done using trivial bit-wise operations - e.g. (a ^ c) & (b ^ c) >= 0
, where a
and b
are the arguments and c
is the result).
PS: if (and that's a big if) the code may not yield false negatives even in cases such as in the "-2" example, it'd be better to keep track of the difference d
between the number of overflows (positive → negative) and the number of underflows (negative → positive), e.g. by if ((a ^ c) & (b ^ c) < 0) d += c < 0 ? -1 : 1;
. CanAdd should then return d == 0
.
The code is correct from a realistic point of view but implements a stricter criterion than actually stated. Consider e.g.:
2147483647 + 2147483647 + (-2147483648) + (-2147483648)
Here, the result could be a "solid" -2 but CanAdd rejects it nevertheless. As such, the code does not satisfy its requirements (but, in this case, I'd almost certainly adjust the requirements instead of the code ;-).
On a more practical note: simply performing each addition (regardless of overflows), followed by a check if the sign of the result is as expected could marginally improve performance (it suffices to check that at least one argument has the same sign as that of the result, which can be done using trivial bit-wise operations - e.g. (a ^ c) & (b ^ c) >= 0
, where a
and b
are the arguments and c
is the result).
PS: if (and that's a big if) the code may not yield false negatives even in cases such as in the "-2" example, it'd be better to keep track of the difference d
between the number of overflows (positive → negative) and the number of underflows (negative → positive). CanAdd should then return d == 0
.
The code is correct from a realistic point of view but implements a stricter criterion than actually stated. Consider e.g.:
2147483647 + 2147483647 + (-2147483648) + (-2147483648)
Here, the result could be a "solid" -2 but CanAdd rejects it nevertheless. As such, the code does not satisfy its requirements (but, in this case, I'd almost certainly adjust the requirements instead of the code ;-).
On a more practical note: simply performing each addition (regardless of overflows), followed by a check if the sign of the result is as expected could marginally improve performance (it suffices to check that at least one argument has the same sign as that of the result, which can be done using trivial bit-wise operations - e.g. (a ^ c) & (b ^ c) >= 0
, where a
and b
are the arguments and c
is the result).
The code is correct from a realistic point of view but implements a stricter criterion than actually stated. Consider e.g.:
2147483647 + 2147483647 + (-2147483648) + (-2147483648)
Here, the result could be a "solid" -2 but CanAdd rejects it nevertheless. As such, the code does not satisfy its requirements (but, in this case, I'd almost certainly adjust the requirements instead of the code ;-).
On a more practical note: simply performing each addition (regardless of overflows), followed by a check if the sign of the result is as expected could marginally improve performance (it suffices to check that at least one argument has the same sign as that of the result, which can be done using trivial bit-wise operations - e.g. (a ^ c) & (b ^ c) >= 0
, where a
and b
are the arguments and c
is the result).
PS: if (and that's a big if) the code may not yield false negatives even in cases such as in the "-2" example, it'd be better to keep track of the difference d
between the number of overflows (positive → negative) and the number of underflows (negative → positive). CanAdd should then return d == 0
.
The code is correct from a realistic point of view but implements a stricter criterion than actually stated. Consider e.g.:
2147483647 + 2147483647 + (-2147483648) + (-2147483648)
Here, the result could be a "solid" -2 but CanAdd rejects it nevertheless. As such, the code does not satisfy its requirements (but, in this case, I'd almost certainly adjust the requirements instead of the code ;-).
On a more practical note: simply performing each addition (regardless of overflows), followed by a check if the sign of the result is as expected could marginally improve performance (it suffices to check that at least one argument has the same sign as that of the result, which can be done using trivial bit-wise operations - e.g. (a ^ c) & (b ^ c) <>= 0
, where a
and b
are the arguments and c
is the result).
The code is correct from a realistic point of view but implements a stricter criterion than actually stated. Consider e.g.:
2147483647 + 2147483647 + (-2147483648) + (-2147483648)
Here, the result could be a "solid" -2 but CanAdd rejects it nevertheless. As such, the code does not satisfy its requirements (but, in this case, I'd almost certainly adjust the requirements instead of the code ;-).
On a more practical note: simply performing each addition (regardless of overflows), followed by a check if the sign of the result is as expected could marginally improve performance (it suffices to check that at least one argument has the same sign as that of the result, which can be done using trivial bit-wise operations - e.g. (a ^ c) & (b ^ c) < 0
, where a
and b
are the arguments and c
is the result).
The code is correct from a realistic point of view but implements a stricter criterion than actually stated. Consider e.g.:
2147483647 + 2147483647 + (-2147483648) + (-2147483648)
Here, the result could be a "solid" -2 but CanAdd rejects it nevertheless. As such, the code does not satisfy its requirements (but, in this case, I'd almost certainly adjust the requirements instead of the code ;-).
On a more practical note: simply performing each addition (regardless of overflows), followed by a check if the sign of the result is as expected could marginally improve performance (it suffices to check that at least one argument has the same sign as that of the result, which can be done using trivial bit-wise operations - e.g. (a ^ c) & (b ^ c) >= 0
, where a
and b
are the arguments and c
is the result).
- 87.3k
- 14
- 104
- 322