photo
+ Responder ao Tópico
Resultados de 1 a 1 de 1

Thread: Tipos de Dados - Tipos Reais (double, float)

  1. #1 Fechar a publicação
    Senior Member
    Data de afiliação
    Aug 2018
    Postagens
    110
    Obrigado
    14
    Agradecimentos 132 Tempos em 53 Postagens
    AssinarAssinar
    subscritar: 0

    Tipos de Dados - Tipos Reais (double, float)

    Tipos Reais (ou tipos de ponto flutuante) representam valores com um parte fracionária. Na linguagem MQL5 existem dois tipos para números de ponto flutuante. O método de representação dos números reais na memória do computador é definido pelo padrão IEEE 754 e é independente de plataformas, sistemas operacionais ou linguagens de programação.

    Name:  Sem título.jpg
Views: 152
Size:  25.9 KB


    O nome double significa que a precisão destes números é duas vezes a precisão dos números do tipo float. Na maioria dos casos, o tipo double é o tipo mais conveniente. Em muitos casos a precisão limitada de números float não é suficiente. O motivo do tipo float ser ainda utilizado é a economia de memória (isto é importante para arrays grandes de números reais).

    Constantes de ponto flutuante consistem de um parte inteira, um ponto (.) e a parte fracionária. As partes inteira e fracionária são seqüências de algarismos decimais.

    Exemplos:

    double a=12.111;
    double b=-956.1007;
    float c =0.0001;
    float d =16;

    Existe uma forma científica de escrever constantes reais, frequentemente este método de notação é mais compacta que a forma tradicional.

    Exemplo:

    double c1=1.12123515e-25;
    double c2=0.000000000000000000000000112123515; // 24 zeros após o ponto decimal

    Print("1. c1 =",DoubleToString(c1,16));
    // Resultado: 1. c1 = 0.0000000000000000

    Print("2. c1 =",DoubleToString(c1,-16));
    // Resultado: 2. c1 = 1.1212351499999999e-025

    Print("3. c2 =",DoubleToString(c2,-16));
    // Resultado: 3. c2 = 1.1212351499999999e-025

    Deve-se lembrar que números reais são armazenados em memória com precisão limitada no sistema binário, apesar da notação decimal ser geralmente usada. É por isso que muitos números que são precisamente representados no sistema decimal só podem ser escritos como fração infinita no sistema binário.

    Por exemplo, os números 0.3 e 0.7 são representados no computador como frações infinitas, enquanto o número 0.25 é armazenado de forma exata, porque ele representa uma potência de dois.

    Neste sentido, recomenda-se fortemente não comparar dois números com igualdade, porque tal comparação não é correta.

    Exemplo:

    void OnStart()
    {
    //---
    double three=3.0;
    double x,y,z;
    x=1/three;
    y=4/three;
    z=5/three;
    if(x+y==z)
    Print("1/3 + 4/3 == 5/3");
    else
    Print("1/3 + 4/3 != 5/3");
    // Resultado: 1/3 + 4/3 != 5/3
    }

    Se você ainda precisa comparar com igualdade dois números reais, então você pode fazer isso de duas maneiras diferentes. A primeira maneira é comparar a diferença entre dois números com alguma quantidade pequena que especifica a precisão da comparação.

    Exemplo:

    bool EqualDoubles(double d1,double d2,double epsilon)
    {
    if(epsilon<0)
    epsilon=-epsilon;
    //---
    if(d1-d2>epsilon)
    return false;
    if(d1-d2<-epsilon)
    return false;
    //---
    return true;
    }
    void OnStart()
    {
    double d_val=0.7;
    float f_val=0.7;
    if(EqualDoubles(d_val,f_val,0.000000000000001))
    Print(d_val," equals ",f_val);
    else
    Print("Diferente: d_val = ",DoubleToString(d_val,16)," f_val = ",DoubleToString(f_val,16));
    // Resultado: Diferente: d_val= 0.7000000000000000 f_val= 0.6999999880790710
    }

    Note que o valor de epsilon no exemplo acima pode ser menor que a constante predefinida DBL_EPSILON. O valor desta constante é 2.2204460492503131e-016. A constante correspondente ao tipo float é FLT_EPSILON = 1.192092896e-07. O significado destes valores é o seguinte: é o menor valor que satisfaz a condição 1.0 + DBL_EPSILON! = 1.0 (para números do tipo float 1.0 + FLT_EPSILON! = 1.0).

    A segunda maneira compara a diferença normalizada de dois números reais com zero. Não faz sentido comparar a diferença de números normalizados com zero, porque qualquer operação matemática com números normalizados dá um resultado não normalizado.

    Exemplo:

    bool CompareDoubles(double number1,double number2)
    {
    if(NormalizeDouble(number1-number2,8)==0)
    return(true);
    else
    return(false);
    }
    void OnStart()
    {
    double d_val=0.3;
    float f_val=0.3;
    if(CompareDoubles(d_val,f_val))
    Print(d_val," iguais ",f_val);
    else
    Print("Diferente: d_val = ",DoubleToString(d_val,16)," f_val = ",DoubleToString(f_val,16));
    // Resultado: Diferente: d_val= 0.3000000000000000 f_val= 0.3000000119209290
    }

    Algumas operações do co-processador matemático podem resultar em um número real inválido, o qual não pode ser usado em operações matemáticas e operações de comparação, porque o resultado de operações com números reais inválidos é indefinido. Por exemplo, quando tentar calcular o arco-seno de 2, o resultado é infinito negativo.

    Exemplo:

    double abnormal = MathArcsin(2.0);
    Print("MathArcsin(2.0) =",abnormal);
    // Resulto: MathArcsin(2.0) = -1.#IND

    Além do menos infinito, existe o mais infinito e o NaN (not a number). Para determinar se um número é inválido, você pode usar MathIsValidNumber(). De acordo com o padrão IEEE, eles tem uma representação de máquina especial. Por exemplo, mais infinito para o tipo double tem a representação binária de 0x7FF0 0000 0000 0000.

    Exemplos:

    struct str1
    {
    double d;
    };
    struct str2
    {
    long l;
    };

    //--- Começo
    str1 s1;
    str2 s2;
    //---
    s1.d=MathArcsin(2.0); // Obtém o número inválido -1.#IND
    s2=s1;
    printf("1. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0xFFFF000000000000; // número inválido -1.#QNAN
    s1=s2;
    printf("2. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0x7FF7000000000000; // maior sem-número SNaN
    s1=s2;
    printf("3. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0x7FF8000000000000; // menor sem-número QNaN
    s1=s2;
    printf("4. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0x7FFF000000000000; // maior sem-número QNaN
    s1=s2;
    printf("5. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0x7FF0000000000000; // // Infinito positivo 1.#INF e menor sem-número SNaN
    s1=s2;
    printf("6. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0xFFF0000000000000; // Infinito negativo -1.#INF
    s1=s2;
    printf("7. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0x8000000000000000; // Zero negativo -0.0
    s1=s2;
    printf("8. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0x3FE0000000000000; // 0.5
    s1=s2;
    printf("9. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0x3FF0000000000000; // 1.0
    s1=s2;
    printf("10. %f %I64X",s1.d,s2.l);
    //---
    s2.l=0x7FEFFFFFFFFFFFFF; // Maior número normalizado (MAX_DBL)
    s1=s2;
    printf("11. %.16e %I64X",s1.d,s2.l);
    //---
    s2.l=0x0010000000000000; // Menor normalizado positivo (MIN_DBL)
    s1=s2;
    printf("12. %.16e %.16I64X",s1.d,s2.l);
    //---
    s1.d=0.7; // Mostra que o número 0.7 é uma fração sem fim
    s2=s1;
    printf("13. %.16e %.16I64X",s1.d,s2.l);
    /*
    1. -1.#IND00 FFF8000000000000
    2. -1.#QNAN0 FFFF000000000000
    3. 1.#SNAN0 7FF7000000000000
    4. 1.#QNAN0 7FF8000000000000
    5. 1.#QNAN0 7FFF000000000000
    6. 1.#INF00 7FF0000000000000
    7. -1.#INF00 FFF0000000000000
    8. -0.000000 8000000000000000
    9. 0.500000 3FE0000000000000
    10. 1.000000 3FF0000000000000
    11. 1.7976931348623157e+308 7FEFFFFFFFFFFFFF
    12. 2.2250738585072014e-308 0010000000000000
    13. 6.9999999999999996e-001 3FE6666666666666
    */

    Though trading on financial markets involves high risk, it can still generate extra income in case you apply the right approach. By choosing a reliable broker such as InstaForex you get access to the international financial markets and open your way towards financial independence. You can sign up here.


  2. Os seguintes 2 Usuários Dizem Obrigado o a BrasilForeingExchange por este post útil:

    Não registrado (2 )

+ Responder ao Tópico

Permissões de postagens

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts