На этот вопрос довольно удобно ответить уже на практике, но есть один момент, о котором я упомяну ниже, который я еще не видел, чтобы кто-то еще поднял его.
Поскольку нам сказали принять a> = 0, а первое условие гарантирует, что b - (a + p)> = 0, заключенный в скобки || тесты можно превратить в тесты на неравенство с 1:
(a + p <= b) && (a! = 1) && (b> = p) && (b - a - p! = 1)
Заманчиво убрать проверку (b> = p), которая дала бы выражение никфа. И это почти наверняка правильное практическое решение. К сожалению, нам нужно больше узнать о проблемной области, прежде чем мы сможем сказать, безопасно ли это делать.
Например, если вы используете C и 32-битные беззнаковые целые для типов a, b и p, рассмотрите случай, когда a = 2 ^ 31 + 7, p = 2 ^ 31 + 5, b = 13. У нас a> 0, (a + p) = 12
Возможно, ваши значения не будут приближаться к диапазонам, в которых возникает переполнение такого рода, но вы должны проверить это предположение. И если это оказывается возможным, добавьте комментарий с этим выражением, объясняющим это, чтобы какой-то ревностный будущий оптимизатор небрежно не удалил тест (b> = p).