Oberon space

General Category => Общий раздел => Тема начата: kkkk от Ноябрь 18, 2016, 03:52:59 pm

Название: Странные битовые операции
Отправлено: kkkk от Ноябрь 18, 2016, 03:52:59 pm
Цитировать
видимо, return  (x > clip_box.x2) | ((x < clip_box.x1) << 2);
на обероне будет как-то так:
RETURN SYSTEM.VAL( UNSIGNED32, SYSTEM.VAL( SET, ORD( x > clipBox.x2 )) + SYSTEM.VAL( SET,  ASH( ORD( x < clipBox.x1 ), 2)));
А почему не так?
RETURN ORD( x > clipBox.x2) + ORD( x < clipBox.x1 ) * 4 Или я что-то упустил? Ещё я не припомню гарантий в описании, что ORD(TRUE) = 1, а ORD(FALSE) = 0, но иначе ORD для BOOLEAN не имел бы смысла.

В Си где только можно использую нормальную арифметику вместо битовых операций и не чувствую, что чего-то не хватает.
Название: Re: Странные битовые операции
Отправлено: Geniepro от Ноябрь 18, 2016, 06:26:11 pm
Так это у них там помешанность на маловразумительном типе SET. Теорию множеств не любят, но множества обожают. Странные они...
Название: Re: Странные битовые операции
Отправлено: Geniepro от Ноябрь 18, 2016, 06:59:05 pm
В Си где только можно использую нормальную арифметику вместо битовых операций и не чувствую, что чего-то не хватает.
Вообще в зависимости от компилятора может порождаться разный по быстродействию код. На такой тестовый пример:
int test(int x, int num1, int num2) {
    return (x > num1) | ((x < num2) << 2);
}

int test2(int x, int num1, int num2) {
    return (x > num1) + (x < num2) * 4;
}
https://godbolt.org/
Компилятор clang 3.9.0 генерирует почти одинаковый код, заменив умножение на сдвиг, разница лишь в том, что он оставляет команды or и add.
Компилятор gcc 6.2 тоже генерирует почти одинаковый код, заменив и умножение, и сдвиг на готовую сдвинутую константу (4), и опять разница лишь в том, что он тоже оставляет команды or и add.
А вот компилятор icc 17, как ни странно, генерирует код, соответствующий коду на си -- то есть в первом случае shl и or, а во втором случае imul и add. Не помню, какие там растактовки команд у современных процессоров, но в принципе код от icc может быть медленнее, чем у других компиляторов, ведь обычно команда умножения гораздо сложнее и дольше, чем сдвига (ну по-крайней мере на старых процессорах).
PS. Впрочем, с включенными оптимизациями код сильно меняется, так что может эти рассуждения и бесполезны, хз...
Название: Re: Странные битовые операции
Отправлено: kkkk от Ноябрь 18, 2016, 09:10:24 pm
Может, современные интелы настолько круты, что умножение на степень 2-ки выполняют столь же быстро, как битовый сдвиг, поэтому интеловский компилятор и не напрягается  ;D ?
Название: Re: Странные битовые операции
Отправлено: trurl от Ноябрь 19, 2016, 01:10:46 pm
Помню как-то хаяли компилятор, который генерировал add 1, а не inc. Как оказалось, актуальный на то время процессор выполнял add быстрее, чем inc.
Название: Re: Странные битовые операции
Отправлено: Kemet от Ноябрь 29, 2016, 04:11:46 am
Цитировать
А почему не так?
RETURN ORD( x > clipBox.x2) + ORD( x < clipBox.x1 ) * 4
Потому что в Активном Обероне нет приведения булевого типа к целому, то есть ORD( TRUE ) не работает. Причем булево даже через SYSTEM.VAL не удастся ни к чему привести.


Название: Re: Странные битовые операции
Отправлено: Geniepro от Ноябрь 29, 2016, 05:20:56 am
Причем булево даже через SYSTEM.VAL не удастся ни к чему привести.
неужели трудно сделать свою процедурку, желательно инлайновую, типа:
PROCEDURE BoolToInt(b: BOOLEAN): INTEGER;
BEGIN
  IF b THEN RETURN 1
       ELSE RETURN 0
  END
END BoolToInt;
Название: Re: Странные битовые операции
Отправлено: kkkk от Ноябрь 29, 2016, 09:49:11 am
Потому что в Активном Обероне нет приведения булевого типа к целому, то есть ORD( TRUE ) не работает. Причем булево даже через SYSTEM.VAL не удастся ни к чему привести.
Тогда я предпочёл бы написать что-то вроде:
IF x > clipBox.x2
THEN ret := 1
ELSE ret := 0
END;
IF x < clipBox.x1
THEN INC(ret, 4)
END;
RETURN  ret
Длинно, зато понятней, чем мегавыражение через SYSTEM да и чем оригинальное Си-выражение, которое, подозреваю, само по себе  банально перевымудренно, и вместо этого нужно что-то поадекватней.
Название: Re: Странные битовые операции
Отправлено: Kemet от Ноябрь 29, 2016, 10:16:38 am
да собственно, когда портируешь достаточно большой проект, отвлекаться на всякую херню, вроде выше предложенной, не айс. Если язык не позволяет адекватно это портировать, значит есть некий дефект в языке. Кстати, даже в Виртовском Обероне и КП это сделать просто - там есть ORD( boolean ), есть ORD( set ) и BITS( int ). Правда и там есть проблема в виде отсутствия сдвигов для SET, впрочем по понятным причинам - не вписываются эти операции в стройную теорию.
Но так-то сейчас эта тема не актуальна - я решил ее несколько иначе.
Название: Re: Странные битовые операции
Отправлено: trurl от Ноябрь 29, 2016, 12:04:38 pm
Нет,  ORD( boolean ) появился только в последних ревизиях оберона. 
Название: Re: Странные битовые операции
Отправлено: Geniepro от Ноябрь 29, 2016, 05:43:33 pm
Нет,  ORD( boolean ) появился только в последних ревизиях оберона.
А ведь это было ещё в древнем паскале. Зачем Вирт его убрал?
Название: Re: Странные битовые операции
Отправлено: Kemet от Ноябрь 30, 2016, 06:12:05 pm
Нет,  ORD( boolean ) появился только в последних ревизиях оберона.
Ну я смотрел древний оберон и там это было