У меня следующее if
состояние.
if (i == -i && i != 0)
Какое значение i
вернет true
для этого условия в Java?
Я не могу придумать какой-либо такой ценности для i
рассмотрения двух дополнений в Java.
Я также хотел бы получить алгебраическое доказательство того, какой ответ это условие имеет (в контексте Java)?
-0.0
это также== 0
if(i && i == -i)
Ответы:
Единственное
int
значение, для которого это работаетInteger.MIN_VALUE
.Это потому, что целые числа инвертируются с использованием способа дополнения до двух .
С помощью
вы видите, что
Integer.MIN_VALUE
этоПринятие отрицательного значения выполняется сначала заменой местами
0
и1
, что даети добавив
1
, что даетКак вы можете видеть в приведенной мной ссылке, Википедия упоминает проблему с наиболее отрицательными числами и указывает ее единственное исключение:
Конечно, у вас будет то же самое явление,
Long.Min_Value
если вы сохраните его вlong
переменной.Обратите внимание, что это связано только с выбором, который был сделан в отношении двоичного хранения int в Java . Другое (плохое) решение могло, например, заключаться в том, чтобы отменить, просто изменив наиболее значимый бит и оставив другие биты неизменными, это позволило бы избежать этой проблемы с MIN_VALUE, но сделало бы 2 разных
0
значения и сложную двоичную арифметику (как бы вы увеличено например?).источник
Ценность, которую вы ищете
Integer.MIN_VALUE
.Это не по теме для Stack Exchange. Но вы могли бы сделать это, начиная с определения целых чисел Java ( JLS 4.2 )
и
и определение унарного оператора Java '-' ( JLS 15.15.4 ):
источник
i != -i
). В диапазоне остаются два числа:0
иInteger.MIN_VALUE
. Из-за того, чтоi != 0
в вашем случае остается толькоMIN_VALUE
.В дополнение к ответам, данным до сих пор ...
Всего существует четыре значения
Обернутые значения разворачиваются, поэтому они также верны для этого выражения.
Примечание: документы Math.abs.
и
Удивительно, что Math.abs может возвращать отрицательное число. Это происходит либо потому, что: а) в этих случаях нет положительных значений для -MIN_VALUE; б) выполнение
-
вычислений приводит к переполнению.Интересно также, почему этого не делают Byte.MIN_VALUE, Short.MIN_VALUE. Это связано с тем, что для них
-
изменяется тип,int
и, следовательно, нет переполнения.Character.MIN_VALUE не имеет проблем, потому что он равен 0.
Float.MIN_VALUE и Double.MIN_VALUE имеют разное значение. Это наименьшее представимое значение больше нуля. Таким образом, они имеют действительные отрицательные значения, которые не являются самими собой.
источник
Как уже упоминалось другими, это выполняется только
Integer.MIN_VALUE
. Что касается доказательства, позвольте мне предложить более легкое для понимания объяснение, отличное от двоичного (хотя оно все еще основано на этом).Обратите внимание, что
Integer.MIN_VALUE
это равно-2^31
или-2147483648
иInteger.MAX_VALUE
равно2^31-1
или2147483647
.-Integer.MIN_VALUE
is2^31
, которое теперь слишком велико для целого числа (поскольку оно прошлоMAX_VALUE
), что вызывает переполнение целого числа, что делает егоInteger.MIN_VALUE
снова. Это единственное целое число, которое делает это, посколькуMIN_VALUE
это единственное число без отрицательного эквивалента, кроме 0.источник
2147483648
может появляться в исходном коде только в одном случае: как операнд унарного оператора минус (JLS 3.10.1).Предварительное алгебраическое доказательство с использованием
modulo 2^32
арифметики:i == -i
можно переписать как2 * i == 0
(добавляяi
с обеих сторон), илиi << 1 == 0
.Это уравнение имеет два решения вида
i == 0 >> 1
:0b
и,10000000000000000000000000000000b
получаемые сдвигом влево0
или1
вправо.Решение
i == 0
исключено, остается решениеi == 100000000000000000000000000000000b
.источник
Возможно, это не слишком поучительно, но вместо того, чтобы думать, что вы можете запустить этот код:
чтобы увидеть, что он печатает
бесконечно :)
источник
<