Всегда ли (x == x + 1) возвращает false для целого числа x? - PullRequest
10 голосов
/ 13 июля 2011

Я видел это в книге подготовки к интервью - Алгоритмы для интервью.Он не сказал, что ответ.

Насколько я знаю, он возвращает false.Я что-то упустил?

Ответы [ 7 ]

12 голосов
/ 13 июля 2011

Javascript приходит мне в голову, у него есть специальное числовое значение Infinity.

Так что на самом деле это вернет true:

var x = Infinity;
alert(x == x + 1);
8 голосов
/ 13 июля 2011

С целыми числами, x != x + 1 для всех х. С числами с плавающей точкой это не гарантируется, чтобы быть правдой; с достаточно большим показателем степени 1 исчезнет в незначительности и будет потерян с конца мантиссы - самый простой случай, чтобы увидеть из максимально возможного показателя, который делает значение бесконечным. А бесконечность плюс один - это бесконечность. Но это будет работать и с меньшими показателями.

Тогда в языках, которые поддерживают перегрузку операторов, вполне возможно нарушить такие тривиальные математические законы. Например, в Python,

>>> class X(object):
...    def __eq__(self, other):
...        return True
...    def __add__(self, other):
...        return self
...
>>> x = X()
>>> x == x + 1
True

Если тип (и реализация) не указан в вопросе, небезопасно предполагать, что это всегда верно. Но так как было указано, что это целое число, вы можете знать, что x != x + 1 для всех х. Целые числа хранятся в виде серии битов, и добавление одного выполняется путем переключения последнего бита и последующего переноса, если он был 1 и так далее , который никогда не даст тот же результат (независимо от количества битов в целочисленном типе, если он больше нуля).

3 голосов
/ 13 июля 2011

C и C ++ не определяют поведение, когда максимальное целочисленное значение со знаком хранит их переполнение. Например, наибольшее допустимое значение типа int известно как INT_MAX (доступно в стандартном заголовке) - эти языки не требуют, чтобы INT_MAX + 1 было чем-то конкретным, то есть они не требуют компиляторы или среды развертывания, чтобы гарантировать, что он все еще не будет INT_MAX. Но они крайне маловероятно (по соображениям производительности) генерировать дополнительное тестирование машинного кода на предмет переполнения при каждой арифметической операции ... скорее, они, как правило, позволяют ЦПУ реагировать на переполнение и выдают тот результат, на который он похож.

На уровне ЦП нет реальной причины, по которой ЦП не может спастись при обнаружении потенциального переполнения, игнорировании добавления или генерации какого-либо исключения: если последнее не распространяется в ОС / приложение или игнорируется ими , тогда можно увидеть исходное значение. Но большинство процессоров обрабатывают «+ 1» для типов со знаком так же, как и для типов без знака, которые C / C ++ требует просто обернуть по модулю 2^#bits ... то, как это интерпретируется как число со знаком, зависит от того, какой из подписанных Количество представлений используется. Для некоторых языков и процессоров могут быть возможны интегральные операции над значениями BCD - еще сложнее предположить, как они реагируют на переполнение.

3 голосов
/ 13 июля 2011

Это зависит от языка и его приоритета оператора.Возможно, оператор == имеет такой же или более высокий приоритет, чем оператор +.В этом случае ваше выражение расширится до ((x == x) + 1), что может привести к ошибке (потому что вы добавляете 1 к логическому значению) или к значению 2 (поскольку во многих языках TRUE равно 1).

Я не знаю, какой, если таковой имеется, язык, где == имеет такой же или более высокий приоритет, чем +.

3 голосов
/ 13 июля 2011

должно:)

это также верно для

x = Int32.MaxValue;
result = x == x + 1;
2 голосов
/ 30 октября 2013

Например, в Java x == x + 1 также может иметь значение true, если код выполняется в нескольких потоках.

Существует вероятность того, что другой поток в это же время изменит x, поэтому условие в конечном итоге может оказаться истинным. Переменная x должна быть объявлена ​​как volatile, чтобы не кэшироваться.

0 голосов
/ 13 июля 2011

Конечно, это должно быть ложно, если вы не делаете то, что говорит Павел;) x + 1 оценивает какое-то значение, которое больше на 1, чем x.Так, например, 45 == 45 + 1 неверно.В этом выражении нет ассигнований.

...