LINUX.ORG.RU

почините быдло-код, с-кодеры

 


0

1

как вот это запилить по-компактнее, не прессуя смайлы и, тем самым, не ухудшая читаемость

      if ( ExtremumBuffer[bar]>ExtremumBuffer[bar+1]   && ExtremumBuffer[bar]<ExtremumBuffer[bar+2]   &&
           ExtremumBuffer[bar+2]>ExtremumBuffer[bar+4] && ExtremumBuffer[bar+3]<ExtremumBuffer[bar+4]
           &&
           (
            (ExtremumBuffer[bar+4]>ExtremumBuffer[bar] && 
            (ExtremumBuffer[bar+4]-ExtremumBuffer[bar])<=MarketInfo(Symbol(),MODE_TICKSIZE)*max_percent_diff)
            ||
            (ExtremumBuffer[bar]>ExtremumBuffer[bar+4] && 
            (ExtremumBuffer[bar]-ExtremumBuffer[bar+4])<=MarketInfo(Symbol(),MODE_TICKSIZE)*max_percent_diff)
           )
           &&
           (
            (
            (ExtremumBufferShift[bar]-ExtremumBufferShift[bar+2])>(ExtremumBufferShift[bar+2]-ExtremumBufferShift[bar+4])
               &&
            ((ExtremumBufferShift[bar]-ExtremumBufferShift[bar+2])/(ExtremumBufferShift[bar+2]-ExtremumBufferShift[bar+4])*100)<=(max_percent_diff+100)
            )
            ||
            (
            (ExtremumBufferShift[bar]-ExtremumBufferShift[bar+2])<(ExtremumBufferShift[bar+2]-ExtremumBufferShift[bar+4])
               &&
            ((ExtremumBufferShift[bar+2]-ExtremumBufferShift[bar+4])/(ExtremumBufferShift[bar]-ExtremumBufferShift[bar+2])*100)<=(max_percent_diff+100)
            )
           )
           &&
           (
            (
            (ExtremumBufferShift[bar+2]-ExtremumBufferShift[bar+1])>(ExtremumBufferShift[bar+3]-ExtremumBufferShift[bar+2])
               &&
            ((ExtremumBufferShift[bar+2]-ExtremumBufferShift[bar+1])/(ExtremumBufferShift[bar+3]-ExtremumBufferShift[bar+2])*100)<=(max_percent_diff+100)
            )
            ||
            (
            (ExtremumBufferShift[bar+2]-ExtremumBufferShift[bar+1])<(ExtremumBufferShift[bar+3]-ExtremumBufferShift[bar+2])
               &&
            ((ExtremumBufferShift[bar+3]-ExtremumBufferShift[bar+2])/(ExtremumBufferShift[bar+2]-ExtremumBufferShift[bar+1])*100)<=(max_percent_diff+100)
            )
           )
           &&
           (
            (
            (ExtremumBufferShift[bar+1]-ExtremumBufferShift[bar])>(ExtremumBufferShift[bar+4]-ExtremumBufferShift[bar+3])
               &&
            ((ExtremumBufferShift[bar+1]-ExtremumBufferShift[bar])/(ExtremumBufferShift[bar+4]-ExtremumBufferShift[bar+3])*100)<=(max_percent_diff+100)
            )
            ||
            (
            (ExtremumBufferShift[bar+1]-ExtremumBufferShift[bar])>(ExtremumBufferShift[bar+4]-ExtremumBufferShift[bar+3])
               &&
            ((ExtremumBufferShift[bar+4]-ExtremumBufferShift[bar+3])/(ExtremumBufferShift[bar+1]-ExtremumBufferShift[bar])*100)<=(max_percent_diff+100)
            )
           )
         )
         {
         bla-bla-bla
         }

★★★★

да, подсветочка херовато работает - ни тебе подсветки смайликов, ни подсветки И/ИЛИ...

megabaks ★★★★
() автор топика

Постараться выделить в условных выражениях некоторые повторяющиеся шаблоны и выделить их в отдельные функции, не забыв им дать осмысленное название

theNamelessOne ★★★★★
()
Ответ на: комментарий от visual

хм...разве что через
bla<foo>bar<hz
но хз
вообще это далеко не все условия, судя по всему

megabaks ★★★★
() автор топика
Ответ на: комментарий от visual

может быть...только надо определиться с кол-вом таких пременных
всё равно это всё внутри for живёт...

megabaks ★★★★
() автор топика
Ответ на: комментарий от megabaks

Ну почему же, навскидку:

(ExtremumBuffer[bar+4]>ExtremumBuffer[bar] && 
            (ExtremumBuffer[bar+4]-ExtremumBuffer[bar])<=MarketInfo(Symbol(),MODE_TICKSIZE)*max_percent_diff)
(ExtremumBuffer[bar]>ExtremumBuffer[bar+4] && 
            (ExtremumBuffer[bar]-ExtremumBuffer[bar+4])<=MarketInfo(Symbol(),MODE_TICKSIZE)*max_percent_diff)

Сейчас времени смотреть код нету, потом еще гляну

theNamelessOne ★★★★★
()
#define delta2(x) (ExtremumBufferShift[x]-ExtremumBufferShift[(x)+2])
#define delta1(x) (ExtremumBufferShift[(x)+1]-ExtremumBufferShift[x])

int px(int x, int y) {
	int t;

	if (x == y)
		return 0;

	if (x > y) {
		t = y;
		y = x;
		x = t;
	}

	return ((y/x*100)<=(max_percent_diff+100));
}

if ( ExtremumBuffer[bar]>ExtremumBuffer[bar+1]   && ExtremumBuffer[bar]<ExtremumBuffer[bar+2]   &&
           ExtremumBuffer[bar+2]>ExtremumBuffer[bar+4] && ExtremumBuffer[bar+3]<ExtremumBuffer[bar+4]
           &&
           (
            (ExtremumBuffer[bar+4]>ExtremumBuffer[bar] && 
            (ExtremumBuffer[bar+4]-ExtremumBuffer[bar])<=MarketInfo(Symbol(),MODE_TICKSIZE)*max_percent_diff)
            ||
            (ExtremumBuffer[bar]>ExtremumBuffer[bar+4] && 
            (ExtremumBuffer[bar]-ExtremumBuffer[bar+4])<=MarketInfo(Symbol(),MODE_TICKSIZE)*max_percent_diff)
           )
           &&
           px(delta2(bar), delta2(bar+2))
           &&
           px(delta1(bar+1), delta1(bar+2))
           &&
           px(delta1(bar), delta1(bar+3))
         )
         {
         bla-bla-bla
         }

Никаких гарантий. Макросы выпилить по вкусу. И да, в последнем условии у тебя ошибка.

AptGet ★★★
()
Ответ на: комментарий от AptGet

твой код на меня тоску наводит
это модно чтоль, давать названия от балды, которые ни о чём не говорят?

megabaks ★★★★
() автор топика
Ответ на: комментарий от anonymous

ты оставил дублирование же

Да, мне лень, дальше тривиально :)

AptGet ★★★
()
Ответ на: комментарий от AptGet

ну можно же использовать всякие count и иже с ним

megabaks ★★★★
() автор топика

Вот ещё один вариант. Я правда не вникал в саму решаемую задачу. Декомпозицию можно нормально делать, только если хорошо знаешь контекст задачи.


//Этот ужас куда-нибудь спрятать, чтобы глаза не мозолил
//============================
inline bool Condition1(SomeType* arr,int bar)
{
  return   arr[bar]>arr[bar+1]   && arr[bar]<arr[bar+2]   &&
           arr[bar+2]>arr[bar+4] && arr[bar+3]<arr[bar+4]
}

inline bool Condition2(SomeType* arr,int bar)
{
  return    (arr[bar+4]>arr[bar] && 
            (arr[bar+4]-arr[bar])<=MarketInfo(Symbol(),MODE_TICKSIZE)*max_percent_diff)
            ||
            (arr[bar]>arr[bar+4] && 
            (arr[bar]-arr[bar+4])<=MarketInfo(Symbol(),MODE_TICKSIZE)*max_percent_diff)
}

inline bool ComplexCondition(SomeType2* arr,int bar, 
int a11,int a12,int a13,int a14,
int a21,int a22,int a23,int a24,
int a31,int a32,int a33,int a34,
int a41,int a42,int a43,int a44)
{
  return
  (
            (arr[bar+a11]-arr[bar+a12])>(arr[bar+a13]-arr[bar+a14]) &&
            ((arr[bar+a21]-arr[bar+a22])/(arr[bar+a23]-arr[bar+a24])*100<=(max_percent_diff+100))
            ||
            ((arr[bar+a31]-arr[bar+a32])<(arr[bar+a33]-arr[bar+a34])&&
            ((arr[bar+a41]-arr[bar+a42])/(arr[bar+a43]-arr[bar+a44])*100)<=(max_percent_diff+100)
  )
}

//============================


//Собственно код

#define EB ExtremumBuffer
#define EBS ExtremumBufferShift

if(
  Condition1(EB,bar)
  &&
  Condition2(EB,bar)
  &&
  ComplexCondition(EBS,bar,
    0,2,2,4,
    0,2,2,4,
    0,2,2,4,
    2,4,0,2)
  &&
  ComplexCondition(EBS,bar,
    2,1,3,2,
    2,1,3,2,
    2,1,3,2,
    3,2,2,1)
  &&
  ComplexCondition(EBS,bar,
    2,1,3,2,
    2,1,3,2,
    2,1,3,2,
    3,2,2,1)  
)
{
  //some code
}
pathfinder ★★★★
()

Делаешь кучу функций типа int (*func)(тип *ExtremumBufferShift). Заносишь указатели на них в массив. В цикле прогоняешь их, пока не кончатся (и возвращаешь не ноль) или попавшаяся выдаст 0 (и возвращаешь ноль). По результату делаешь if.

O02eg ★★★★★
()

(a && b) || (a && c) = a && (b || c) как минимум. Там три больших куска можно оптимизировать.

anonymous
()

И брось программирование, это не твое.

anonymous
()

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

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

\n
это так модно :3
я же так пишу всегда
пора привыкнуть
а про переменные не догнал
что именно не нравится?

megabaks ★★★★
() автор топика
Ответ на: комментарий от anonymous

(a && b) || (a && c) = a && (b || c) как минимум. Там три больших куска можно оптимизировать.

где ты увидел оптимизацию? Если a ложно, то b и c вычисляться не будут, и результат будет 0. Если a истинно, то по любому надо считать b, затем c, а затем их дизъюнкцию. И где ты увидел экономию?

И брось программирование, это не твое.

а ты не бросай изучать на полдороге.

drBatty ★★
()
Ответ на: комментарий от drBatty

хотя случай не так и прост - a необходимо в случае (a && b) || (a && c) вычислять таки ДВАЖДЫ, ибо компилятор не уверен об отсутствии побочных эффектов. Потому, в общем случае, второе вычисление a может дать ИНОЙ результат, если в первом случае a == 0. Потому такая «оптимизация» опасна, и может привести к поломке программы после рефакторинга. Особенно «смешно» будет, если a обычно == 1, и/или побочный эффект редко влияет на что-то. Тогда бага успешно переживёт тестирование, и вылезет в продакшене.

drBatty ★★
()
Ответ на: комментарий от urxvt

Ну и \n вокруг круглых скобок это еще круче.

в таком быдлокоде это необходимо. Особенно учитывая, что быдлокодер ещё и запихнул эти макароны в for(;;). Ему я даже писать ничего не буду, он на меня обиделся, и заигнорил...

drBatty ★★
()
Ответ на: комментарий от anonymous

На пайтоне бы в одну строчку решил... Кто меньше?

блжд...

sed -ri 's/\s+/ /'

превратит любой код на C в однострок. Единственное, директивы препроцессора надо раскрыть.

drBatty ★★
()

Комментарий телепата

  • Числа с плавающей точкой записываются как «100.0», а не «100». Можно добавить окончание, чтобы ещё более точно определить тип константы.
  • Числа с плавающей точкой не используются при обработке финансовой информации.
Deleted
()
Ответ на: комментарий от Deleted

Числа с плавающей точкой очень внезапно и непредсказуемо теряют точность 8).

ну вообще-то, если у нас FPU это i8087 (или аналог), и мы не выходим за 2^64, то таки можно и FloatingPoint юзать. ИЧСХ - юзают. Давно и успешно. Intel гарантирует это, инфа 146%.

drBatty ★★
()
Ответ на: комментарий от Deleted

внезапно и непредсказуемо

ну не так уж и «внезапно», в даташитах всё подробно расписано.

drBatty ★★
()
Ответ на: комментарий от Deleted

это всё для графики
минимальный шаг по вертикали может составлять , например, 0.0001
короче - минимальное изменение цены
округление тут просто абсурдно

megabaks ★★★★
() автор топика

1. Разложить условное выражение на части.

2. Поместить их в do { ... } while (0); и выходить из цикла с помощью break.

3. Попробовать применить макросы.

gatsu
()
Ответ на: комментарий от megabaks

О, тогда прошу прощения за бесполезный совет, не в курсе особенностей MQL.

gatsu
()

Поработаю за К.О. с небольшим опытом быдлокодера.

1. Все большое выражение сделать отдельной функцией 6 переменных: ExtremumBufferShift[bar] ... ExtremumBufferShift[bar+4], max_percent_diff (если это не константа).

2. Дать входным параметрам этой функции осмысленные имена.

3. Сделать из одного if, несколько: разбить большое выражение на более мелкие, сгруппировать условия по смыслу. Если одно из условий не выполняется - return false.

Кода получится даже больше, но пользоваться, отлаживать и расширять будет проще.

qaqa ★★
()
Ответ на: комментарий от megabaks

а про переменные не догнал что именно не нравится?

Их длина избыточна.

urxvt ★★★★★
()
Ответ на: комментарий от drBatty

ну вообще-то, если у нас FPU это i8087 (или аналог), и мы не выходим за 2^64, то таки можно и FloatingPoint юзать.

Дело не в overflow/underflow, а именно в представлении чисел. Вот например: мы точно знаем, что пять рублей и двадцать копеек - это ровно столько и есть, то есть пять рублей и двадцать копеек (как ни странно). Но у IEEE 754 другое мнение на этот счёт:

$ cat test.c 
#include <stdio.h>

int main(void)
{
	printf("%.40f\n", 5.20);
	return 0;
}

$ gcc -o test test.c 

$ ./test 
5.2000000000000001776356839400250464677811
Сама по себе погрешность очень маленькая и на единичных операциях проявляться не будет. Но со временем она накопится и кому-то придётся закупать вазелин =).

Кроме накопления ошибки есть ещё одна проблема: обнаружение равенства двух значений. Два выражения, которые математически дают один и тот же результат, в числах с плавающей точкой могут давать разный результат. Причём разница может быть как очень маленькой, так и очень большой - в зависимости от порядка действий и разнице в используемых величинах.

Deleted
()
Ответ на: комментарий от Deleted

Сама по себе погрешность очень маленькая и на единичных операциях проявляться не будет. Но со временем она накопится и кому-то придётся закупать вазелин =).

ССЗБ

#include <stdio.h>

int main(void)
{
		printf("%.40f\n", 520.0);
			return 0;
}
$ ./a.out 
520.0000000000000000000000000000000000000000

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

может ты просто не умеешь их готовить?

drBatty ★★
()
Ответ на: комментарий от drBatty

ССЗБ

И чем это отличается от int'ов? =)

может ты просто не умеешь их готовить?

Да нет, вроде умею...

Deleted
()
Ответ на: комментарий от Deleted

И чем это отличается от int'ов? =)

ну они 64х битные. Это раньше было очень актуально. Сейчас тоже, ибо простые intы они на многих платформах 32х битные.

ну вот например такой код:

#include <stdio.h>

int main(void)
{
	double x = 1.0;
	int j;
	for(j = 0; j < 64; j++)
		x *= 2;
	printf("%.40f\n", x);
	return 0;
}
выдаёт 18446744073709551616.0000000000000000000000000000000000000000

но если на x686 заменить double на int, то получается 0... Как видишь, тут точность НЕ страдает.

Да нет, вроде умею...

просто для ЛЮБЫХ типов надо соблюдать осторожность. Для double на i8087 просто нельзя выходить за рамки целого 0 <= x <= 2^64. Тогда всё точно получается, и double (с этими условиями) годен для финансовых рассчётов. В отличие от int, который _может_ переполнится и для 65536 единиц.

drBatty ★★
()
Ответ на: комментарий от drBatty

ну они 64х битные. Это раньше было очень актуально. Сейчас тоже, ибо простые intы они на многих платформах 32х битные.

Есть стандарнтый ini64_t, можно использовать его. Если его не хватит - можно использовать gcc-специфичный __uint128_t. Далее идут GMP и другие подобные библиотеки.

Как видишь, тут точность НЕ страдает.

В данном случае ты double используешь как int. Естественно точность не страдает...

просто для ЛЮБЫХ типов надо соблюдать осторожность.

Тут я согласен.

Для double на i8087 просто нельзя выходить за рамки целого 0 <= x <= 2^64.

Зачем использовать double, когда можно сразу использовать целочисленные типы?

Deleted
()
Ответ на: комментарий от Deleted

Есть стандарнтый ini64_t, можно использовать его. Если его не хватит - можно использовать gcc-специфичный __uint128_t. Далее идут GMP и другие подобные библиотеки.

ну кто же спорит? просто использование FPU - это один из вариантов. Если всё делать аккуратно, то никакого вазелина не нужно. :-)

В данном случае ты double используешь как int. Естественно точность не страдает...

ну не так уж и «есстественно». С каким угодно FPU точность может и пострадать. Может пострадать и на i8087, если выйдти за границу 2^64. Даже если всё в целых.

Зачем использовать double, когда можно сразу использовать

целочисленные типы?

про double в i8087 нам точно известно, что потери точности не будет. Кроме того, рассчёты будут выполнятся _одновременно_ с другими операциями (ибо сопроцессор). Ну и 64х битное целое складывается/умножается намного дольше, чем double на 32х битной платформе. (A*M + B) * (C*M + D) = A*C*M^2 + A*D*M + B*C*M + D*B, как видишь, для умножения двух 64х битных чисел нам придётся выполнить 4 умножения и ещё 3 сложения. В случае double это может занять вообще НОЛЬ времени, ибо вычисления будут выполняться параллельно с другими действиями (даже на древних процессорах типа i80486).

drBatty ★★
()
char ediffshift(double * ebufshift, int i, int j, int k, int l, double maxdiff) {
  if ((ebufshift[i] - ebufshift[j]) > (ebufshift[k] - ebufshift[l]))
    return (100 * (ebufshift[i] - ebufshift[j]) / (ebufshift[k] - ebufshift[l]) < 100 + maxdiff);
  else
    return (100 * (ebufshift[k] - ebufshift[l]) / (ebufshift[i] - ebufshift[j]) < 100 + maxdiff);
}

if ((ebuf[bar] > ebuf[bar+1]) && (ebuf[bar] < ebuf[bar+2])
  && (ebuf[bar+2] > ebuf[bar+4]) && (ebuf[bar+3] < ebuf[bar+4])
  && (abs(ebuf[bar] - ebuf[bar+4]) <= MarketInfo(Symbol(), MODE_TICKSIZE) * maxdiff)
  && ediffshift(ebufshift, 0, 2, 2, 4, maxdiff)
  && ediffshift(ebufshift, 2, 1, 3, 2, maxdiff)
  && ediffshift(ebufshift, 1, 0, 4, 3, maxdiff)) {
    bla-bla-bla;
}
N
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.