NormalizeDouble kullanarak MT4'te sayıları yuvarlama - sayfa 16

 
fxsaber :
kullanımdan kaldırıldı

Standart kitaplık , granülasyonu hesaba katan bir fiyat normalleştirme işlevine sahiptir.

 //+------------------------------------------------------------------+
//| Normalize price                                                  |
//+------------------------------------------------------------------+
double CSymbolInfo::NormalizePrice( const double price) const
  {
   if (m_tick_size!= 0 )
       return ( NormalizeDouble ( MathRound (price/m_tick_size)*m_tick_size,m_digits));
//---
   return ( NormalizeDouble (price,m_digits));
  }
 
Slawa :

Standart kitaplık , granülasyonu hesaba katan bir fiyat normalleştirme işlevine sahiptir.

Bu son derece yavaş uygulamanın farkında. NormalizeDouble'ı (ve Yardımı) mevcut gerçekliklere sonlandırmakla ilgiliydi. Herkes kendi granülasyonlarını yazabilir.
 
transcendreamer :
NormalizeDouble(new_lot-sum_lots, Lots_Digits); olduğunu tahmin etmeye başladım bile. tam olarak 0 vermez ama bir tür kuyruk tutar

Yeni_lot ve toplam_lot değişkenleri eşitse, fark tam olarak 0 olacaktır. Ancak bunları nasıl hesapladığınız bilinmiyor, aslında hesaplamalarda eşit olmadıkları ortaya çıkabilir, dolayısıyla sıfır olmayan fark. Aynısını şu şekilde yapın:

NormalizeDouble (new_lot, Lots_Digits) - NormalizeDouble(sum_lots, Lots_Digits).

Değişkenler belirtilen basamak sayısı içinde eşitse, fark kesinlikle 0 olacaktır.

 
Sergei Vladimirov :

Yeni_lot ve toplam_lot değişkenleri eşitse, fark tam olarak 0 olacaktır. Ancak bunları nasıl hesapladığınız bilinmiyor, aslında hesaplamalarda eşit olmadıkları ortaya çıkabilir, dolayısıyla sıfır olmayan fark. Aynısını şu şekilde yapın:

NormalizeDouble(new_lot, Lots_Digits) - NormalizeDouble(sum_lots, Lots_Digits).

Değişkenler belirtilen basamak sayısı içinde eşitse, fark kesinlikle 0 olacaktır.

teşekkür ederim!
 
transcendreamer :

Ve yine yuvarlama hakkında ......

duruma göre söyleyin lütfen (domates atmayın ben hümanistim),

bu değişken var:

      double delta=NormalizeDouble(new_lot-sum_lots,Lots_Digits);

      if(delta>0) delta-=OrderLots();

      if(delta<0) delta+=OrderLots();

teorik olarak delta başlangıçta normalleştirilir,

OrderLots muhtemelen normalleştirilmiş çiftleri döndürmelidir,

ama bir şekilde bazen nadir durumlarda 2.775557561562891e-17 gibi sayılar alıyorum

yani neredeyse sıfır ama sıfır değil ......

İlk soru, bu normal mi?

...


Daha dikkatli tekrar okudum. Nifiga normal değil. NormalizeDouble işlevi nasıl çalışır:

  1. Bütün kısım göze çarpıyor - ben
  2. Kesirli kısım vurgulanır - F
  3. F = F * 10^basamak
  4. F = F (+ veya - işarete bağlı olarak) 0,5
  5. F = (F'nin tamsayı kısmı) / 10^basamak
  6. sonuç = I + F
o zaman NormalizeDouble(new_lot - sum_lots, Lots_Digits) sonucu, yeni_lot ve toplam_lotlar belirtilen basamak sayısı içinde eşitse kesinlikle sıfır olmalıdır. Nadir durumlarda, son basamakta 1'lik bir fark olabilir (nedeni 4. ve 5. noktalardadır), ancak sonuç 2.775557561562891e-17 - bu garip, bu olmamalı.
 

Yüzen bir sayının içini tersine çeviren küçük bir öğretici kod yazdım (kendimle uğraşmak eğlenceliydi). İlgilenen varsa çalıştırabilir (C++ kodu, bazı çevrimiçi derleyicileri kullanabilirsiniz. Burada https://goo.gl/tP691X , örneğin)

 #include <iostream>
using namespace std;

int main()
{
    cout.precision( 17 );
     float f = 0.5 ;
     //float add = 0.00000002980232239; //-25   1/(2^25)
     float add = 0.00000005960464478 ; //-24     1/(2^24)
     //float add = 0.0000001192092896; //-23   1/(2^23)
     //float add = 0.0000002384185791; // -22  1/(2^22)
    f+= add;

    cout << "value = " << f << endl;
    cout << "----------\n" ;

     char *c = ( char *)&f;  // char может ссылаться на любой тип
    cout << "mantissa:\n" ;
    cout << "implicit_1 " ;
    cout << (c[ 2 ] >> 6 & 0 b1) << ' ' ; cout << (c[ 2 ] >> 5 & 0 b1) << ' ' ;
    cout << (c[ 2 ] >> 4 & 0 b1) << ' ' ; cout << (c[ 2 ] >> 3 & 0 b1) << ' ' ;
    cout << (c[ 2 ] >> 2 & 0 b1) << ' ' ; cout << (c[ 2 ] >> 1 & 0 b1) << ' ' ;
    cout << (c[ 2 ] >> 0 & 0 b1) << ' ' ; cout << (c[ 1 ] >> 7 & 0 b1) << ' ' ;
    cout << (c[ 1 ] >> 6 & 0 b1) << ' ' ; cout << (c[ 1 ] >> 5 & 0 b1) << ' ' ;
    cout << (c[ 1 ] >> 4 & 0 b1) << ' ' ; cout << (c[ 1 ] >> 3 & 0 b1) << ' ' ;
    cout << (c[ 1 ] >> 2 & 0 b1) << ' ' ; cout << (c[ 1 ] >> 1 & 0 b1) << ' ' ;
    cout << (c[ 1 ] >> 0 & 0 b1) << ' ' ; cout << (c[ 0 ] >> 7 & 0 b1) << ' ' ;
    cout << (c[ 0 ] >> 6 & 0 b1) << ' ' ; cout << (c[ 0 ] >> 5 & 0 b1) << ' ' ;
    cout << (c[ 0 ] >> 4 & 0 b1) << ' ' ; cout << (c[ 0 ] >> 3 & 0 b1) << ' ' ;
    cout << (c[ 0 ] >> 2 & 0 b1) << ' ' ; cout << (c[ 0 ] >> 1 & 0 b1) << ' ' ;
    cout << (c[ 0 ] >> 0 & 0 b1) << '\n' ;
    cout << "exponenta E - 127:\n" ;
    cout << "1= " << (c[ 2 ] >> 7 & 0 b1) << '\n' ;
    cout << "2= " << (c[ 3 ] >> 0 & 0 b1) << '\n' ;
    cout << "4= " << (c[ 3 ] >> 1 & 0 b1) << '\n' ;
    cout << "8= " << (c[ 3 ] >> 2 & 0 b1) << '\n' ;
    cout << "16= " << (c[ 3 ] >> 3 & 0 b1) << '\n' ;
    cout << "32= " << (c[ 3 ] >> 4 & 0 b1) << '\n' ;
    cout << "64= " << (c[ 3 ] >> 5 & 0 b1) << '\n' ;
    cout << "128= " << (c[ 3 ] >> 6 & 0 b1) << '\n' ;
    cout << "sign\n" ;
    cout << (c[ 3 ] >> 7 & 0 b00000001) << '\n' ;
}

f == 0,5 + 1/(2^24) konumunda egzoz. 1/(2^24) - belirli bir derecede mantisin en az anlamlı basamağı:

value = 0.50000005960464478
----------
mantissa:
implicit_1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
exponenta E - 127 :
1 = 0
2 = 1
4 = 1
8 = 1
16 = 1
32 = 1
64 = 1
128 = 0
sign
0

Derece = 126 - 127 = -1

Mantis = 1.0000000000000000000000001

Mantileri bir kuvvetle kaydırın -1 = 0.100000000000000000000001 = 1^(-1) + 1^(-24) = 1/(2^1) + 1/(2^24) = 0.5 + 0.00000005960464478 = 0.50000005960464478


Teori olarak https://habrahabr.ru/post/112953/ .

Not: bu çevrimiçi derleyici daha iyi olacaktır http://rextester.com/l/cpp_online_compiler_gcc

 
pavlick_ :

Yüzen bir sayının içini tersine çeviren küçük bir öğretici kod yazdım (kendimle uğraşmak eğlenceliydi). İlgilenen varsa çalıştırabilirsiniz (C++ kodu, bazı çevrimiçi derleyicileri kullanabilirsiniz. Burada https://www.tutorialspoint.com/compile_cpp11_online.php , örneğin)

Ayrıca MQL5'te çalıştırabilirsiniz - bu kitaplığı ekleyerek c[Pos]'u _R(f)[(char)Pos] (veya _R(f.Bytes[Pos]) ile değiştirin.

not

 #include "fmtprntl.mqh"      // https://www.mql5.com/en/blogs/post/680570
#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

#define c _R(f).Bytes
#define endl "\n"

void OnStart ()
{
  OutputStream cout( 16 , ' ' );
  
   float f = 0.5 ;
   //float add = 0.00000002980232239; //-25   1/(2^25)
   float add = 0.00000005960464478 ; //-24     1/(2^24)
   //float add = 0.0000001192092896; //-23   1/(2^23)
   //float add = 0.0000002384185791; // -22  1/(2^22)
  f+= add;

  cout << "value = " << f << endl;
  cout << "----------\n" ;

  cout << "mantissa:\n" ;
  cout << "implicit_1 " ;
  cout << (c[ 2 ] >> 6 & 1 ) << ' ' ; cout << (c[ 2 ] >> 5 & 1 ) << ' ' ;
  cout << (c[ 2 ] >> 4 & 1 ) << ' ' ; cout << (c[ 2 ] >> 3 & 1 ) << ' ' ;
  cout << (c[ 2 ] >> 2 & 1 ) << ' ' ; cout << (c[ 2 ] >> 1 & 1 ) << ' ' ;
  cout << (c[ 2 ] >> 0 & 1 ) << ' ' ; cout << (c[ 1 ] >> 7 & 1 ) << ' ' ;
  cout << (c[ 1 ] >> 6 & 1 ) << ' ' ; cout << (c[ 1 ] >> 5 & 1 ) << ' ' ;
  cout << (c[ 1 ] >> 4 & 1 ) << ' ' ; cout << (c[ 1 ] >> 3 & 1 ) << ' ' ;
  cout << (c[ 1 ] >> 2 & 1 ) << ' ' ; cout << (c[ 1 ] >> 1 & 1 ) << ' ' ;
  cout << (c[ 1 ] >> 0 & 1 ) << ' ' ; cout << (c[ 0 ] >> 7 & 1 ) << ' ' ;
  cout << (c[ 0 ] >> 6 & 1 ) << ' ' ; cout << (c[ 0 ] >> 5 & 1 ) << ' ' ;
  cout << (c[ 0 ] >> 4 & 1 ) << ' ' ; cout << (c[ 0 ] >> 3 & 1 ) << ' ' ;
  cout << (c[ 0 ] >> 2 & 1 ) << ' ' ; cout << (c[ 0 ] >> 1 & 1 ) << ' ' ;
  cout << (c[ 0 ] >> 0 & 1 ) << '\n' ;
  cout << "exponenta E - 127:\n" ;
  cout << "1= " << (c[ 2 ] >> 7 & 1 ) << '\n' ;
  cout << "2= " << (c[ 3 ] >> 0 & 1 ) << '\n' ;
  cout << "4= " << (c[ 3 ] >> 1 & 1 ) << '\n' ;
  cout << "8= " << (c[ 3 ] >> 2 & 1 ) << '\n' ;
  cout << "16= " << (c[ 3 ] >> 3 & 1 ) << '\n' ;
  cout << "32= " << (c[ 3 ] >> 4 & 1 ) << '\n' ;
  cout << "64= " << (c[ 3 ] >> 5 & 1 ) << '\n' ;
  cout << "128= " << (c[ 3 ] >> 6 & 1 ) << '\n' ;
  cout << "sign\n" ;
  cout << (c[ 3 ] >> 7 & 1 ) << '\n' ;
}

Sonuç

 2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       0
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)      sign
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       128 =   0
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       64 =   1
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       32 =   1
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       16 =   1
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       8 =   1
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       4 =   1
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       2 =   1
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       1 =   0
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)      exponenta E - 127 :
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       implicit_1   0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 1
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       mantissa:
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)       ----------
2016.09 . 27 23 : 56 : 01.178 Test (Si- 12.16 ,H1)      value =   0.5000000596046448 
 
implicit_1   0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 0 32 1

Mantis'e ne oldu?

32, sorunun ascii kodudur. Hatalı kitaplığın char için bir sürümü yok gibi görünüyor. Mantislerin değerleri arasındaki boşlukları kaldırmamız gerektiğini düşünüyorum. Ya da belki " " yazmak yerine ?

 
pavlick_ :

Mantis'e ne oldu?

32, sorunun ascii kodudur. Hatalı bir kütüphaneye benziyor. Mantislerin değerleri arasındaki boşlukları kaldırmamız gerektiğini düşünüyorum. Ya da belki " " yazmak yerine ?

fmtprntl.mqh benim değil, bu yüzden kesin bir şey söyleyemem.

Rahatsız etmek istemiyorum, bu yüzden f'niz için bayt değerlerini yazdırdım

 2016.09 . 28 00 : 34 : 09.813 Test (Si- 12.16 ,H1)      c[ 0 ] = 1
2016.09 . 28 00 : 34 : 09.813 Test (Si- 12.16 ,H1)      c[ 1 ] = 0
2016.09 . 28 00 : 34 : 09.813 Test (Si- 12.16 ,H1)      c[ 2 ] = 0
2016.09 . 28 00 : 34 : 09.813 Test (Si- 12.16 ,H1)      c[ 3 ] = 63
 
Slawa :

İlişkili yan etki.

Uygun olduğu ortaya çıktı. Ancak bu kullanım başlangıçta amaçlanmamıştır.

Gerçek bir sayıyı gerekli doğrulukta yazdırmak için özel işlevler vardır.

Söyle bana, hesaplama sürecinde neden gerçek sayıları yuvarlamanız gerekiyor? Gerçekten de, bu durumda, hesaplamaların doğruluğu kaybolur!

fiyatların, durakların, lotların doğru karşılaştırmasından bahsediyoruz

biraz kesinlik olması gerekiyor