Автор Тема: Странные битовые операции  (Прочитано 16354 раз)

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Странные битовые операции
« : Ноябрь 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 не имел бы смысла.

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

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #1 : Ноябрь 18, 2016, 06:26:11 pm »
Так это у них там помешанность на маловразумительном типе SET. Теорию множеств не любят, но множества обожают. Странные они...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #2 : Ноябрь 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. Впрочем, с включенными оптимизациями код сильно меняется, так что может эти рассуждения и бесполезны, хз...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #3 : Ноябрь 18, 2016, 09:10:24 pm »
Может, современные интелы настолько круты, что умножение на степень 2-ки выполняют столь же быстро, как битовый сдвиг, поэтому интеловский компилятор и не напрягается  ;D ?

trurl

  • Full Member
  • ***
  • Сообщений: 133
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #4 : Ноябрь 19, 2016, 01:10:46 pm »
Помню как-то хаяли компилятор, который генерировал add 1, а не inc. Как оказалось, актуальный на то время процессор выполнял add быстрее, чем inc.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #5 : Ноябрь 29, 2016, 04:11:46 am »
Цитировать
А почему не так?
RETURN ORD( x > clipBox.x2) + ORD( x < clipBox.x1 ) * 4
Потому что в Активном Обероне нет приведения булевого типа к целому, то есть ORD( TRUE ) не работает. Причем булево даже через SYSTEM.VAL не удастся ни к чему привести.



Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #6 : Ноябрь 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;
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #7 : Ноябрь 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 да и чем оригинальное Си-выражение, которое, подозреваю, само по себе  банально перевымудренно, и вместо этого нужно что-то поадекватней.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #8 : Ноябрь 29, 2016, 10:16:38 am »
да собственно, когда портируешь достаточно большой проект, отвлекаться на всякую херню, вроде выше предложенной, не айс. Если язык не позволяет адекватно это портировать, значит есть некий дефект в языке. Кстати, даже в Виртовском Обероне и КП это сделать просто - там есть ORD( boolean ), есть ORD( set ) и BITS( int ). Правда и там есть проблема в виде отсутствия сдвигов для SET, впрочем по понятным причинам - не вписываются эти операции в стройную теорию.
Но так-то сейчас эта тема не актуальна - я решил ее несколько иначе.

trurl

  • Full Member
  • ***
  • Сообщений: 133
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #9 : Ноябрь 29, 2016, 12:04:38 pm »
Нет,  ORD( boolean ) появился только в последних ревизиях оберона. 

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #10 : Ноябрь 29, 2016, 05:43:33 pm »
Нет,  ORD( boolean ) появился только в последних ревизиях оберона.
А ведь это было ещё в древнем паскале. Зачем Вирт его убрал?
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Странные битовые операции
« Ответ #11 : Ноябрь 30, 2016, 06:12:05 pm »
Нет,  ORD( boolean ) появился только в последних ревизиях оберона.
Ну я смотрел древний оберон и там это было