Erreurs, bugs, questions - page 2622

 

Pourquoi à la ligne 3 :

  datetime dt = 0;
  ulong x = 0;
  if(dt < x) x++;

avertissement de "non-concordance des signes" ?

Datetime est censé être un nombre non signé (8 octets comme ulong). Donnez-moi un exemple de date négative.

 

Dites-moi comment déboguer les bibliothèques ex5 ?

Il existe une bibliothèque qui a fonctionné pendant plusieurs années sans aucun problème. Cependant, après certaines modifications du compilateur dans les dernières versions, un appel de fonction pointeur à partir de la bibliothèque se termine par une erreur "appel de fonction pointeur non valide". Si la source de la bibliothèque est incluse dans l'Expert Advisor directement par le lien, il n'y a pas d'erreur.

En général, vous avez besoin d'un moyen de comparer les types de pointeurs(prototypes de fonction), générés dans la bibliothèque et dans le conseiller expert, qui charge la bibliothèque.

Le support est fermé. Je ne montrerai pas ici le code source de la place de marché.

Pour référence, avec le même code source, l'appel à la bibliothèque a bien fonctionné dans la version 2190.
 
Stanislav Korotky:

Pour référence, avec le même code source, un appel à partir de la bibliothèque a fonctionné correctement dans la version 2190.

En 2170 je n'ai plus de pointeurs vers les fonctions, voici un exemple qui fonctionne toujours dans MQL4, mais qui ne fonctionne plus dans MQL5

https://www.mql5.com/ru/forum/323539/page3#comment_13444791

 
Igor Makanu:

J'ai arrêté de travailler avec les pointeurs de fonction en 2170. Voici un exemple qui fonctionne toujours dans MQL4, mais qui a cessé de fonctionner dans MQL5

https://www.mql5.com/ru/forum/323539/page3#comment_13444791

Je l'ai lu. J'ai un cas différent. Mais c'est probablement la conséquence du même "serrage de vis". Cependant, les bonnes pratiques dans ce cas impliquent des instructions humaines pour la migration des développements existants avec des exemples ou la disponibilité d'un étrier.

 

Des mathématiques assez divertissantes

//+------------------------------------------------------------------+
double volume_step = 0.01;
void OnStart()
  {
   int total = 10;
   double aVolume = 0.01;
   
   for(int i=0; i<total; i++)
     {
      aVolume = volume_step * MathFloor(aVolume / volume_step);
      Print(DoubleToString(aVolume,8)+"   "+ DoubleToString(volume_step,2)+"   "+DoubleToString(MathFloor(aVolume / volume_step),2)+"  Next lot = "+(aVolume+0.01));
      aVolume+=0.01;
     }
  }
//+------------------------------------------------------------------+

Résultat

2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00 Prochain lot = 0.06999999999999999
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00 Prochain lot = 0.069999999999999
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00 Prochain lot = 0.069999999999999
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00 Prochain lot = 0.069999999999999
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00 Prochain lot = 0.06999999999999999Comme 0.06000000 + 0.01 devient 0.0699999999999
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.05000000 0.01 5.00 Prochain lot = 0.06
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.04000000 0.01 4.00 Prochain lot = 0.05
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.03000000 0.01 3.00 Prochain lot = 0.04
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.02000000 0.01 2.00 Prochain lot = 0.03
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.01000000 0.01 1.00 Prochain lot = 0.02


 
Vladimir Pastushak:

Des mathématiques tout à fait remarquables

Comment 0,06000000 + 0,01 devient-il 0,06999999999999999999999 ?

parce que 0.06999999999999999999999 est le nombre le plus proche de 0.07 qui peut être représenté par le type double

 
Vladimir Pastushak:

Des mathématiques assez divertissantes

Résultat

2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00 Prochain lot = 0.069999999999999
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00 Prochain lot = 0.069999999999999
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00 Prochain lot = 0.069999999999999
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.06000000 0.01 6.00 Prochain lot = 0.06999999999999999 Comme 0.06000000 + 0.01 devient 0.0699999999999
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.05000000 0.01 5.00 Prochain lot = 0.06
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.04000000 0.01 4.00 Prochain lot = 0.05
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.03000000 0.01 3.00 Prochain lot = 0.04
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.02000000 0.01 2.00 Prochain lot = 0.03
2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0.01000000 0.01 1.00 Prochain lot = 0.02


Lisez les docks et vous serez heureux.

Et sur le sujet : IEEE 754, - étudiez-le.

 
Igor Makanu:

parce que 0.06999999999999999999999 est le nombre le plus proche de 0.07 qui peut être représenté par le type double

Vladimir Simakov:

Lisez les docs et vous serez heureux.

Sur le sujet : IEEE 754, - étude.

Qu'est-ce que vous lui apprenez... il a 49 produits publiés sur le marché. Il sait déjà tout lui-même....
 
Alexey Viktorov:
Qu'est-ce que vous lui apprenez... il a 49 produits publiés sur le marché. Il sait déjà tout lui-même....

Donc, vous suggérez que ceux qui postent sur le Marché devraient être ignorés ? Je ne suis pas sûr de vouloir faire ça, il y a eu une question, une discussion, je pense que c'est une situation normale.

PS :

en plus de cela .... essayez de désimprimer un double via printf(), j'ai le sentiment qu'il y aura beaucoup de "combien de découvertes merveilleuses l'esprit des lumières nous prépare-t-il...".

;)

 
Vladimir Pastushak:

Des mathématiques assez divertissantes

Résultat

2020.01.05 17:09:28.798 Testert EURUSD,H1 : 0 .06000000 0.01 6.00

C'est une question récurrente.
Tout le monde parle toujours de la norme IEEE 754, mais souvent, lorsque les gens vont sur Wikipédia, soit par complexité, soit par paresse, ils repartent sans avoir compris la signification de la norme.

Je vais prendre un peu de temps pour essayer d'expliquer cette norme le plus brièvement possible et avec des mots simples, afin de faire référence à ce post.


Ainsi, le type double est constitué de 8 octets = 64 bits.(float 4 bytes = 32 bits)

Et la représentation numérique dudouble et du flottant se compose de 3 éléments : lesigne, l'exposant et la mantisse.


DOUBLE :


FLOAT :

Naturellement, il n'existe pas de représentation décimale des nombres dans ce format, mais uniquement binaire.

  • Le signe est de 1 bit. Si 0, c'est + (plus), si 1, c'est - (moins).
  • L'exposant stocke le degré du numéro 2. Peut se situer dans la plage -12610 à 12710 pour les flottants et -1022 10 à 102310 pour les doubles.
  • La mantisse est la partie fractionnaire du nombre lui-même sous forme binaire, réduite à une forme dans laquelle la virgule est placée après la première unité sans tenir compte de cette première unité et de la virgule.


Une petite compréhension de la représentation binaire des nombres et de sa relation avec les nombres décimaux :

24= 100002 = 1610

23= 10002 = 810

22= 1002 = 4

21=102= 2

20=12=110

2-1= 0.12 =(1/2)10= 0.510

2-2= 0.012 = (1/4)10= 0.2510

2-3= 0.0012 = (1/8)10= 0.12510

2-4= 0.00012 = (1/16)10= 0.062510

2-5= 0.000012 = (1/32)10= 0.0312510

2-6= 0.0000012 = (1/64)10= 0.01562510

2-7= 0.00000012 = (1/128)10= 0.007812510

2-8= 0.000000012 = (1/256)10= 0.0039062510

2-9= 0.0000000012 = (1/512)10= 0.00195312510

2-10= 0.00000000012 = (1/1024)10= 0.000976562510

2-11= 0.000000000012 = (1/2048)10= 0.0004882812510

2-12= 0.0000000000012 = (1/4096)10= 0.00024414062510

2-13= 0.00000000000012 = (1/8192)10= 0.000122070312510

Prenons des exemples pour le type double:

Exemple 1

Nous avons un nombre décimal : 891677.4025191

Ce nombre peut être représenté sous forme binaire :

1101100110110001110101.01100111000010110111111111011000101000001111111010001110
(qui veut peut vérifier)))

Nous extrayons la mantisse du nombre donné en déplaçant simplement la virgule de 19 chiffres vers la gauche (dans ce cas), de sorte qu'elle se trouve après la première unité.

1.1011001101100011101011001110000101101111101111000101000001111101110001110* 219

Mais nous avons une mantisse de seulement 52 bits. Donc on prend les 52 premiers bits significatifs

Мантисса = 1011001101100011101011001110000101101111101111000101

Exposant = (19+1023)10 = 100000100102(comme l'exposant est un nombre signé et que l'exposant peut être négatif (par exemple si nous avons 0.0000042132), nous devons ajouter 1023 à10(01111111111112), 011111111112 est zéro, tout ce qui est plus est positif, moins est négatif. En d'autres termes, pour obtenir la valeur inverse de l'exposant, nous devons soustraire 1023 de la valeur de l'exposant sur 11 bits.

Au total, notre numéro 891677.4025191 se présentera comme suit en type double:

0100000100101011001101100011101011001110000101101111101111000101

Mais comme il s'agit d'une représentation binaire, convertissons-la exactement en décimal :

ce serait891677.40251909999996425211429595947265625


Exemple n° 2

Nous avons un nombre décimal : -0.00000145258556224114

Ce nombre peut être représenté sous forme binaire :

-0.000000000000000000011000010111101100111010110111010011010101001111001110

Nous extrayons la mantisse de ce nombre en déplaçant simplement la virgule de 20 chiffres vers la droite, de sorte qu'elle se trouve après le premier.

1.1000010111101100111010110111010011010101001111001110 * 2-20

Мантисса = 1000010111101100111010110111010011010101001111001110

exposant = (-20+1023)10=011111010112

signe moins, donc le premier bit est 1.

Notre nombre total -0,00000145258556224114 se présentera comme suit en caractères doubles :

1011111010111000010111101100111010110111010011010101001111001110

le convertir exactement en décimal :

это будет -0.00000145258556224113991124017968015191826225418481044471263885498046875



Dans votre cas, le problème se pose avec le nombre 0,01, puisque dans le type double il sera représenté sous la forme :

0 01111111000 0100011110101110000101000111101011100001010001111011

qui, converti dans le système de notation décimale, est égal à 0,010000000000000000208166817117216858513294309377670288085937510

Considérant qu'avec la représentation

310 = 1.5*2 = 1.12*21

510 = 2.5*2 = 10.12*21

610 = 1.5*4 = 1.12*22

710 = 3.5*2 = 11.12*21

pas de problème.

Pourquoi le nombre double 0,01 est-il vraiment supérieur à 0,01 ?

Voici pourquoi :

0 01111111000 01000111101101011101000010111101011101001010001111011 - 0,010000000000000000000020816681711721685132943093776702880859375 erreur = 0,000 000 000 000 000 000 208166817...

0 0111111111000 01000111101101011100001011110111001010001111010 - 0.00999999999999999998474734433411404097569175064563751220703125 erreur = - 0.000 000 000 000 000 000 001 5265566...

Pour comprendre ce processus chimique, vous pouvez jouer avec ces calculatrices :
https://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html

https://baseconvert.com/ieee-754-floating-point