Преобразование типа отрицательного значения в char [duplicate]

?: используется, если вы хотите сгруппировать выражение, но вы не хотите сохранять его в качестве согласованной / захваченной части строки.

Примером может быть что-то, что соответствует IP-адресу адрес:

/(?:\d{1,3}\.){3}\d{1,3}/

Обратите внимание, что я не забочусь о сохранении первых 3 октетов, но группировка (?:...) позволяет мне сократить регулярное выражение, не налагая накладные расходы на захват и сохранение соответствия.

5
задан Rollerball 2 March 2013 в 17:22
поделиться

2 ответа

Почему не выдают ошибку компиляции или исключение времени выполнения?

Поскольку спецификация языка требует, чтобы арифметика на примитивных типа была по модулю 2^width, поэтому -1 становится 2^16-1 как char.

В разделе о целых операциях указано, что

Встроенный целочисленные операторы никак не указывают на переполнение или недополнение.

, чтобы запретить бросать исключение.

Для используемого оператора postfix-декремента, в частности, его поведение указанный в 15.14.3

В противном случае значение 1 вычитается из значения переменной, а разница сохраняется в переменной. Перед вычитанием выполняется двоичное числовое продвижение (§5.6.2) на значение 1 и значение переменной. При необходимости различие сужается сужением примитивного преобразования (п. 5.1.3) и / или подвергается конверсии бокса (п. 5.1.7) к типу переменной до ее сохранения. Значение выражения постфиксного декремента - это значение переменной до того, как будет сохранено новое значение.

Двоичное числовое продвижение преобразует оба значения: 1 и int (поскольку тип здесь char), таким образом, у вас есть промежуточный результат -1 как int, тогда выполняется сужающее примитивное преобразование:

Сужение преобразования знакового целого числа в интегральный тип T просто отбрасывает все, кроме n бит младшего разряда, где n - количество бит, используемых для представления типа T. В дополнение к возможной потере информации о величине числового значения это может привести к признаку результата значение отличается от знака входного значения.

, что приводит к char значению 0xFFFF (поскольку Java указывает двоичное представление представления для его знаковых целых типов, явно указанных в спецификация унарный минус ):

Для целых значений отрицание такое же, как и вычитание от нуля. Язык программирования Java использует представление двух дополнений для целых чисел, а диапазон значений двух дополнений не является симметричным, поэтому отрицание максимального отрицательного int или long приводит к тому же максимальному отрицательному числу. В этом случае происходит переполнение, но исключение не генерируется. Для всех целочисленных значений x, -x равно (~ x) +1.

Для общего поведения обертывания для результатов вне диапазона в качестве примера в спецификация оператора умножения :

Если целочисленное умножение переполняется, то результатом являются младшие биты математического произведения, представленные в некотором достаточно большом формате с двумя дополнениями. В результате, если происходит переполнение, знак результата может быть не таким, как знак математического произведения двух значений операнда.

Подобные фразы встречаются в спецификации целочисленное сложение и вычитание требуются для выполнения a - b == a + (-b), поэтому следует поведение переполнения.

15
ответ дан Daniel Fischer 27 August 2018 в 09:35
поделиться

Потому что именно так определяется язык Java. Время выполнения не проверяет границы при каждой операции (вероятно, потому, что это будет чрезвычайно дорого). Он просто переполняется или переполняется.

1
ответ дан JB Nizet 27 August 2018 в 09:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: