Skip to main content
Code Review

Return to Answer

added 59 characters in body
Source Link

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.

typo
Source Link

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.

added 1 character in body
Source Link

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).

Add the algorithm from a comment - it wasn't obvious to me until I saw it.
Source Link
Toby Speight
  • 87.3k
  • 14
  • 104
  • 322
Loading
Source Link
Loading
lang-java

AltStyle によって変換されたページ (->オリジナル) /