WHRoeder: este código é bom (especialmente cheque "adicionado" e "padrão")? Pode também servir como uma referência final fácil para aqueles que visitam este tópico e vão apenas à última página (como eu fiz)
#define LT 0#define GT 1#define GTE 2#define LTE 3#define EQ 4#define NEQ 5bool doublecomp(double a,int type,double b){
// See https://forum.mql4.com/45053/page4// 0 compare doesn't need this functionswitch(type){
case LT: return(b-a>Point/2.);
case GT: return(a-b>Point/2.);
case GTE: return(a-b>-Point); // Addedcase LTE: return(b-a>-Point); // Addedcase EQ: return(!(MathAbs(a-b)>Point/2.));
case NEQ: return(MathAbs(a-b)>Point/2.);
default: return(-1); // Added - needed to avoid compile error about not all control paths returning a value
}
}
SDC: Como se( !MathAbs( a - b ) > Ponto/2) pode ser usado para comparar para igualdade? Isso lhe diria 1,4999 == 1,5000
Não
if( ! (MathAbs( a - b ) > Point/2) ) be used to compare for equality? That would tell you 1.4999 == 1.5000 if( ! (MathAbs(1.4999 - 1.5000 > 0.00005 ) if( ! (0.0001 > 0.00005 ) if( ! (true ) if( false ) 1.4999 is NOT equal to 1.5000
E eu havia apontado para Roel13 em um PM que o GEQ/LEQ deve ser -Point/2, mas ele não editou o posto
E, como já informei anteriormente, você só tem que se preocupar com tais disparates se a igualdade/não-equidade for importante. Se você quiser abrir acima do alto de uma vela, importa se (por causa do arredondamento) ela pode acionar exatamente no alto? Se não usar apenas lance > alto[].
#define LT 0#define GT 1#define GTE 2#define LTE 3#define EQ 4#define NEQ 5bool ComparePrice(double a,int type,double b){
// See https://forum.mql4.com/45053/page4// 0 compare doesn't need this functionswitch(type){
case LT: return(b-a>Point/2.);
case GT: return(a-b>Point/2.);
case GTE: return(a-b>-Point/2.);
case LTE: return(b-a>-Point/2.);
case EQ: return(!(MathAbs(a-b)>Point/2.));
case NEQ: return(MathAbs(a-b)>Point/2.);
}
return(-1);
}
E, talvez uma função secundária para comparar todas as outras duplas que não são preços.
bool CompareNormal(double a,int type,double b){
// With thanks https://forum.mql4.com/45053/page4// 0 compare doesn't need this functionswitch(type){
case LT: return(b-a>0.0000000000000000000000000000001);
case GT: return(a-b>0.0000000000000000000000000000001);
case LTE: return(b-a>-0.0000000000000000000000000000001);
case GTE: return(a-b>-0.0000000000000000000000000000001);
case EQ: return(!(MathAbs(a-b)>0.0000000000000000000000000000001));
case NEQ: return(MathAbs(a-b)>0.0000000000000000000000000000001);
}
return(-1);
}
Veja também 'MQL4 Reference > Language Basics > Data Types > Real Types (double, float)' em relação ao uso de um número pequeno para comparação.
Talvez alguém saiba escrever 0,00....1 melhor em expo
Notado que o valor do epsilon no exemplo acima não pode ser inferior à constante predefinida DBL_EPSILON. O valor desta constante é 2,2204460492503131e-016.
Novamente, nada disso é necessário, exceto no caso em que o igual/não igual é importante. Por exemplo, abra acima da alta anterior, você não quer abrir na alta devido ao arredondamento.
Portanto, há algo mais interessante que encontrei, potencialmente em conexão com a "// 0 compare não precisa desta função".
Talvez um bug apenas nas versões mais recentes, não tenho certeza. A comparação com 0 não funciona mais corretamente. Tive que recorrer a algo pouco amigável como;
Acho que este tópico é tratado com demasiada complexidade desnecessária.
Tente tornar a vida de seu programador sempre tão fácil quanto possível. Escreva definições (ou vá em frente com métodos se realmente for necessário) naquelas aulas em que você precisa de suas comparações duplas:
// add more floating point zeros if you need a higher precision
#define isZero(x) (fabs(x) < 0.000000001)
#define isEqual(x,y) (fabs(x-y) < 0.000000001)
Quando você precisar comparar duas duplas, use-as em uma condição como esta:
if (isEqual(myFirstDouble, mySecondDouble))
{
// first and second doubles are considered equal// do something
}
Se você quiser ver se um duplo é zero (ou muito, muito próximo de zero), use uma condição como esta:
if (isZero(myDouble))
{
// myDouble is considered zero// do something
}
Em uma nota lateral, já que vejo muitos posts falando sobre divisões:
Com o encapsulamento, tendemos a esquecer os custos do código que é "terceirizado" para alguns métodos de utilidade. Lembrem-se de queas divisões são computacionalmente muito caras! Especialmente, uma vez envoltas em métodos utilitários agradáveis em algum lugar nas classes de utilidade, começamos a usá-las em todos os lugares em indicadores ou EAs e há muito tempo esquecemos que passos computacionais eles executam. Quando usamos o testador de estratégia, pagamos muito tempo desnecessário por nosso desleixo.
Regra de ouro: As adições e subtrações são muito mais rápidas do que as multiplicações e divisões. A operação de divisão leva o maior tempo de computação.Otimize as divisões- sempre que possível! Se o denominador for fixo como neste loop...
então substitua o denominador x por seu valor invertido 1/x:
for(int i=0; i < rates_total; i++)
{
// ...double fraction = 0.01 * someNumeratorValue; // replace a denominator with it's inverted value, if possible.
// ...
}
Além disso, se o resultado de uma divisão for sempre o mesmo, então faça o cálculo uma vez e salve o resultado em uma variável para que você possa usá-la em qualquer lugar em seu código (por exemplo, em loops):
double tradesPerDay = totalTradesPerYear/365;
for(int i=0; i < rates_total; i++)
{
// use precomputed tradesPerDay rather than computing the division here.
}
WHRoeder: este código é bom (especialmente cheque "adicionado" e "padrão")? Pode também servir como uma referência final fácil para aqueles que visitam este tópico e vão apenas à última página (como eu fiz)
Esse código não é preciso.
Como se( !MathAbs( a - b ) > Ponto/2) pode ser usado para comparar para igualdade? Isso lhe diria 1,4999 == 1,5000
if( ! (MathAbs(1.4999 - 1.5000 > 0.00005 )
if( ! (0.0001 > 0.00005 )
if( ! (true )
if( false ) 1.4999 is NOT equal to 1.5000
Eu uso
ou para o dobro que arn preços reais, uma maior precisão
Raptors postam sobre este código
Portanto, se você usar,
Testei esse método de várias maneiras e não encontrei um cenário em que ele não retornasse o resultado esperado ou desejado.Código final... Obrigado WHRoeder
E, talvez uma função secundária para comparar todas as outras duplas que não são preços.
Veja também 'MQL4 Reference > Language Basics > Data Types > Real Types (double, float)' em relação ao uso de um número pequeno para comparação.
Talvez alguém saiba escrever 0,00....1 melhor em expo
Portanto, há algo mais interessante que encontrei, potencialmente em conexão com a "// 0 compare não precisa desta função".
Talvez um bug apenas nas versões mais recentes, não tenho certeza. A comparação com 0 não funciona mais corretamente. Tive que recorrer a algo pouco amigável como;
outcome=(int(outcome*100)/100.0); // Resolução 2 dígitos
Apenas para garantir que os valores 0 realmente acabassem como valores 0.
WHRoeder, obrigado. Mais estudos necessários :)
Acho que este tópico é tratado com demasiada complexidade desnecessária.
Tente tornar a vida de seu programador sempre tão fácil quanto possível. Escreva definições (ou vá em frente com métodos se realmente for necessário) naquelas aulas em que você precisa de suas comparações duplas:
Quando você precisar comparar duas duplas, use-as em uma condição como esta:
Se você quiser ver se um duplo é zero (ou muito, muito próximo de zero), use uma condição como esta:
Em uma nota lateral, já que vejo muitos posts falando sobre divisões:
Com o encapsulamento, tendemos a esquecer os custos do código que é "terceirizado" para alguns métodos de utilidade. Lembrem-se de queas divisões são computacionalmente muito caras! Especialmente, uma vez envoltas em métodos utilitários agradáveis em algum lugar nas classes de utilidade, começamos a usá-las em todos os lugares em indicadores ou EAs e há muito tempo esquecemos que passos computacionais eles executam. Quando usamos o testador de estratégia, pagamos muito tempo desnecessário por nosso desleixo.
Regra de ouro: As adições e subtrações são muito mais rápidas do que as multiplicações e divisões. A operação de divisão leva o maior tempo de computação.Otimize as divisões- sempre que possível! Se o denominador for fixo como neste loop...
então substitua o denominador x por seu valor invertido 1/x:
Além disso, se o resultado de uma divisão for sempre o mesmo, então faça o cálculo uma vez e salve o resultado em uma variável para que você possa usá-la em qualquer lugar em seu código (por exemplo, em loops):
Abraço,
A.T.