как запрограммировать такое выражение? - страница 2

 
Для ненулевых можно просто:
y = x / MathAbs(x)



Думаю, быстрее сравнений будет.

Для сравнения с переходом(как и для других использованных операций) есть прямые ассемблерные команды. С делением ситуация, по моим представлениям, сложнее. Ну и сколько операций сидит в MathAbs, неизвестно(мне). Впрочем, тут тест просто нужен, мне тоже интересно :)
 
Тема кажется приобрела некоторую избыточность :), но раз я вначале дал ошибочный рецепт, так просто уйти от неё не могу :). Я сделал проверку для случая +- 1 (поскольку неясно, нужно ли сохранять модуль y). Вот код:
int init()
  {
  int rng = 100000000;
  int i;
  datetime T0,T1,T2,T3,T4;
  int y = 1;
  T0 = LocalTime();
  for (i=-rng;i<rng;i++) {
     y = (1 - 2*(i^y)>>31);
  }
  T1 = LocalTime();
  for (i=-rng;i<rng;i++) {
     if(i<0) y=-1; else y=1;
  }
  T2 = LocalTime();
  for (i=-rng;i<rng;i++) {
     if(((i^y)>>31)) y=-y;
  }
  T3 = LocalTime();
  for (i=-rng;i<0;i++) {
     y = i / MathAbs(i);
  }
  for (i=1;i<rng;i++) {
     y = i / MathAbs(i);
  }
  T4 = LocalTime();
  Print("Вариант 1: ",T1-T0,"с   ","Вариант 2: ",T2-T1,"с   ","Вариант 3: ",T3-T2,"с   ","Вариант 4: ",T4-T3,"с   "); 
   return(0);
  }

Вот лог:

2006.01.11 11:02:42	Timetest EURUSD,M1: Вариант 1: 7с   Вариант 2: 3с   Вариант 3: 10с   Вариант 4: 40с   


P.S. Для сохранения модуля y преимущество у варианта 1

 
почему для Т4 2 цикла?
а мой вариант проверить? :)
 
почему для Т4 2 цикла?
Один до 0, другой после. В сумме на 1 прогон меньше. Иначе нужно добавлять проверку на 0 в цикле. То есть условия были льготные :).
а мой вариант проверить? :)
А я думал ты проверил уже и молчишь :). Я правильно понял, что твой вариант направился к (x>>31)*2-1 ? Вообще-то я проверю :), сегодня просто реформу компьютера затеял. Я хочу проверить ещё MatAbs(), возможно в критических местах для неё лучше использовать inline подстановку типа обсуждавшихся здесь.
 
мой на 10% медленнее второго варианта. наверное, из-за умножения. :)

зато гораздо лаконичнее :p

где inline-подстановки обсуждали???
 
где inline-подстановки обсуждали???
Я думал, что здесь :)
Ещё тест, часть старые, часть про MathAbs.
Код:
int init()
  {
  int rng = 100000000;
  int i;
  datetime T0,T1,T2,T3,T4,T5,T6,T7,T8;
  int y = 1;
  int absY;
  T0 = LocalTime();
  for (i=-rng;i<rng;i++) {
//     y = y*(1 - 2*(i^y)>>31);
     y = (i>0)*2-1;
  }
  T1 = LocalTime();
  for (i=-rng;i<rng;i++) {
     y = 1 - 2*(i>>31);
  }
  T2 = LocalTime();
  for (i=-rng;i<rng;i++) {
//     if(((i^y)>>31)) y=-y;
     if(i<0) y=-1; else y=1;
  }
  T3 = LocalTime();
  for (i=-rng;i<rng;i++) {
     y = MathAbs(i);
  }
  T4 = LocalTime();
  for (i=-rng;i<rng;i++) {
     y = y*(1-2*(y>>31));
  }
  T5 = LocalTime();
  for (i=-rng;i<rng;i++) {
     y = y*(2*(y>0)-1);
  }
  T6 = LocalTime();
  for (i=-rng;i<rng;i++) {
    if(y<0) absY=-y; else absY=y;
  }
  T7 = LocalTime();
  for (i=-rng;i<rng;i++) {
  }
  T8 = LocalTime();
  Print("Исходный вариант: ",T1-T0,"с");
  Print("Вариант со сдвигом: ",T2-T1,"с");
  Print("Лобовая if-else: ",T3-T2,"с");
  Print("MathAbs: ",T4-T3,"с");
  Print("Эквивалент MathAbs, вариант 1: ",T5-T4,"с");
  Print("Эквивалент MathAbs, вариант 2: ",T6-T5,"с");
  Print("Эквивалент MathAbs, вариант 3: ",T7-T6,"с");
  Print("Пустой цикл: ",T8-T7,"с"); 
   return(0);
  }


Результат:

12:01:14 Timetest EURUSD,M1: Исходный вариант: 7с
12:01:14 Timetest EURUSD,M1: Вариант со сдвигом: 7с
12:01:14 Timetest EURUSD,M1: Лобовая if-else: 3с
12:01:14 Timetest EURUSD,M1: MathAbs: 26с
12:01:14 Timetest EURUSD,M1: Эквивалент MathAbs, вариант 1: 8с
12:01:14 Timetest EURUSD,M1: Эквивалент MathAbs, вариант 2: 7с
12:01:14 Timetest EURUSD,M1: Эквивалент MathAbs, вариант 3: 3с
12:01:14 Timetest EURUSD,M1: Пустой цикл: 2с
Причина обращения: