char_x <(char_y + 1) == char_x <= char_y? - PullRequest
       5

char_x <(char_y + 1) == char_x <= char_y?

11 голосов
/ 21 ноября 2011

Привет всем, что я просматривал в исходном коде Java, когда натолкнулся на это (java.lang.Character):

public static boolean isHighSurrogate(char ch) {
    return ch >= MIN_HIGH_SURROGATE && ch < (MAX_HIGH_SURROGATE + 1);
}

public static boolean isLowSurrogate(char ch) {
    return ch >= MIN_LOW_SURROGATE && ch < (MAX_LOW_SURROGATE + 1);
}

Мне было интересно, почему автор добавил 1 к верхнему пределу и делалсравнение меньше, чем просто сравнение меньше или равно?

Я могу понять, помогает ли это читабельности, но в данном случае это не так.

Мне было интересно, в чем разница между кодом выше и этим:

public static boolean isHighSurrogate(char ch) {
    return ch >= MIN_HIGH_SURROGATE && ch <= MAX_HIGH_SURROGATE;
}

public static boolean isLowSurrogate(char ch) {
    return ch >= MIN_LOW_SURROGATE && ch <= MAX_LOW_SURROGATE;
}

Ответы [ 4 ]

2 голосов
/ 21 ноября 2011

Дикая догадка

Суррогатный символ, любой из диапазона кодовых точек Unicode, которые используются в парах в UTF-16 для представления символов за пределами базовой многоязычной плоскости.* На мой взгляд, он хотел игнорировать 8-битные вещи, то есть, если максимальное значение было 0xFF.0xFF + 1 переполнится и вернется к 0x00.Делая сравнение всегда ложным.

Так что, если код был скомпилирован с 8-битными символами.Он всегда будет возвращать false (вне диапазона UTF-16), в то время как если он скомпилирует символ в> 8 битах, 0xFF + 1 будет 0x100 и все еще будет работать.1011 *

2 голосов
/ 21 ноября 2011

Возможно, автор пытается согласиться с советом Дейкстры сделать все диапазоны полуоткрытыми - начальная точка является включающей, а конечная точка - исключительной.

Семантической нетздесь есть разница, но небольшая разница в байт-коде: (ch + 1) - это int, поэтому первый фрагмент кода выполняет сравнение char до char, за которым следует сравнение int до int, а второе - два char char сравнений.Это не приводит к семантическому различию - неявное приведение к более широким типам, и поэтому нет риска переполнения в любом фрагменте кода.

Оптимизация добавления и преобразование int в intсравнение обратно в 2-байтовое беззнаковое int сравнение вполне вписывается в рамки видов оптимизации, выполняемой JIT, поэтому я не вижу какой-либо конкретной причины производительности, чтобы отдавать предпочтение одной над другой.

Я склоненнаписать такую ​​вещь как

MIN_LOW_SURROGATE <= ch && ch <= MAX_LOW_SURROGATE

таким образом, ch в середине делает очевидным для читателя, что ch тестируется в диапазоне внешних значений.

0 голосов
/ 21 ноября 2011

Потому что автором был C ++ или ассемблер.

Это быстрее сделать> = чем> и это быстрее сделать <= чем <.На самом деле, когда вы пишете a <b, компилятор делает a <= b + 1, поэтому он делает сложение и сравнение, потому что единственная доступная инструкция по сборке делает <=.Если вы напишите эту сумму в коде вручную, компилятор C ++ изменит MIN_HIGH_SURROGATE + 1 с фактическим значением результата во время компиляции.Таким образом, вы получаете инструкцию и цикл.</p>

Но все эти странные рассуждения применимы только для скомпилированного кода, такого как C ++ или C. Или ASM.

EDIT

Хотя есть инструкции длякаждый из приведенных выше операторов равенства (я был не прав), все они сводятся к вычитаниям и (при необходимости) дополнениям в микрокоде.Затем процессор проверяет знаковый бит результата.Таким образом, приведенная выше формулировка кода будет по-прежнему быстрее.

Чтобы избежать переполнения при добавлении 1, микропроцессор сначала вычитает, а затем добавляет одно.

0 голосов
/ 21 ноября 2011

Я бы сказал, что нет никакой разницы между двумя способами его кодирования, это просто вопрос вкуса, который вы бы предпочли, поскольку у вас нет никаких преимуществ одной из двух различных реализаций.

Мне было интересно, почему автор добавил 1 к верхнему пределу и сделал сравнение меньше, чем просто сравнение меньше или равно?

Я имею в виду, почему вы предпочитаете второй вариант?Я что-то здесь скучаю?

...