Здравствуйте, Сергей Мухин, Вы писали:
СМ>версия компилятора? СМ>опции компилятора? СМ>с генеренный код?
Компилятор gcc для микроконтроллера AVR, если интересно. Я-то думал, может есть какие-то предложения "в общем виде". Т.е. более эффективное выражение для определения попадания переменной d в диапазон (m — cost)...(m + const)
Здравствуйте, Сергей Мухин, Вы писали:
СМ>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, 777777w, Вы писали:
7>>>Можно ли как-то более эффективно записать выражение
7>>>
7>>>Компилятор генерирует больно уж длинный код
J>>судя по тому, что у тебя написано, условие эквивалентно J>>
J>>if ( abs( Depth - MarkH[0] ) < 20 )
J>>
J>>ы?
СМ>НЕТ!
СМ>например может быть перекрыта [] или тут возможно переполнение на — или даже на abs. или наоборот отсутсвовать переполнение на +-20.
а в чем прблема, если она перекрыта корректно (т.е. если она дает одно и то же для одного и того же аргумента)?
А типа MarkH[0]+20 от переполнения гарантировано?
Имхо, если мы боимся переполнения (т.е. ожидаем соответствующие данные, то и надо выбирать типы, с которыми переполнения не будет, например, разрядность увеличить или вообще в double перейти).
Здравствуйте, Сергей Мухин, Вы писали:
СМ>НЕТ!
СМ>например может быть перекрыта [] или тут возможно переполнение на — или даже на abs. или наоборот отсутсвовать переполнение на +-20.
Скорее всего это все экзотика, но, конечно, только автор может решить, так это или нет.
СМ>>например может быть перекрыта [] или тут возможно переполнение на — или даже на abs. или наоборот отсутсвовать переполнение на +-20.
J>а в чем прблема, если она перекрыта корректно (т.е. если она дает одно и то же для одного и того же аргумента)?
это твое предположение, а еще мб побочный эффект
J>А типа MarkH[0]+20 от переполнения гарантировано?
нет конечно, но это будет другое переполнение! При других значениях! т.е. программа другая
J>Имхо, если мы боимся переполнения (т.е. ожидаем соответствующие данные, то и надо выбирать типы, с которыми переполнения не будет, например, разрядность увеличить или вообще в double перейти).
вот я и говорю, надо _полный_п пример приводить. с типами хотя бы.
СМ>это твое предположение, а еще мб побочный эффект
ага, а еще операторы < и && тоже переопределены и форматируют винчестер.
про переполнения и побочные эффекты — это тоже твое предположение.
Давай нам лучше автор вопроса про все это расскажет — есть у него переполнения или нет, есть побочные эффекты или нет.
А без этого — я предпочитаю пользоваться бритвой Оккама и предлагать и предполагать простейшее, а не тратить время на обсуждение сферопереполнений.
А если мои предположения неверны — так автор вопроса об этом и скажет.
Здравствуйте, jazzer, Вы писали:
J>судя по тому, что у тебя написано, условие эквивалентно J>
J>if ( abs( Depth - MarkH[0] ) < 20 )
J>
J>ы?
Боялся что для этого тупо вызовется библиотечная функция, но ради смеха попробовал — оказалось нет, компилятор понимает abs сам и генерирует на него довольно хитрый код, почти на 50 байт короче.
Здравствуйте, 777777w, Вы писали:
7>Здравствуйте, jazzer, Вы писали:
J>>судя по тому, что у тебя написано, условие эквивалентно J>>
J>>if ( abs( Depth - MarkH[0] ) < 20 )
J>>
J>>ы?
7>Боялся что для этого тупо вызовется библиотечная функция, но ради смеха попробовал — оказалось нет, компилятор понимает abs сам и генерирует на него довольно хитрый код, почти на 50 байт короче.
да вроде абс должен тупо обнулить знаковый бит, и все, если у тебя знаковый тип, естественно.
Здравствуйте, 777777w, Вы писали:
7>Здравствуйте, jazzer, Вы писали:
J>>да вроде абс должен тупо обнулить знаковый бит, и все, если у тебя знаковый тип, естественно.
7> В дополнительном-то коде? Обнулить знаковый бит?
я бы не рассматривал — это, скорее всего, дорогая операция. Соль там в другом, если выполнение MarkH[0] дорого — разумно вызывать один раз.
Далее, ты сам сказал компилятору использовать ленивые вычисления — если у проца есть предсказатель, получим промахи в 50% случаев.
Поэтому можно попробовать:
const int h = MarkH[0];
if ( (h - 20 - Depth) // форсируем знаковый бит, если MarkH[0]-20 < Depth
& (Depth - h - 20) // аккумулируем со знаковым битом 2го условия
& (1 << sizeof(int) * CHAR_BIT - 1) ) // пробуем оптимизировать < 0
{
}
Осталось разобраться с ошибками и кросплатформенностью
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, 777777w, Вы писали:
7>Компилятор gcc для микроконтроллера AVR, если интересно.
Возможно, что у него с оптимизацией в этом месте возникли проблемы.
Например, если Depth и/или MarkH — volatile, то компилятор не может (может не?) взять их значения один раз.
Инлайновая функция тебя спасёт
inline bool in_vicinity(int x, int x0, int d)
{
// такreturn x0-d < x && x < x0+d;
// или такreturn abs(x-x0) < d;
}
.....
if(in_vicinity(Depth, MarkH[0], 20))
.....
если а < в, то а < х < в = х — а — 1 < в — а — 1
второе сравнение беззнаковое, это доказано в книжке Уоррена — алгорит. трюки. стр.64
пишу с телефона, кратко
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, 777777w, Вы писали:
7>>Здравствуйте, jazzer, Вы писали:
J>>>да вроде абс должен тупо обнулить знаковый бит, и все, если у тебя знаковый тип, естественно.
7>> В дополнительном-то коде? Обнулить знаковый бит?
J>в дополнительном, конечно, небольшой гемор.
вы видели когда-нить -1 в машинном представлении???
все единицы. если скинуть знаковый бит будет maxInt.