Erreurs, bugs, questions - page 711

 
sergeev:
Utilisez les cours.

Oui, c'est ça. Je n'avais pas réalisé. Je ne m'en souviens même pas, ça a déjà été suggéré.

C'est comme ça que ça s'est passé :

struct Buff { double b[]; };
//---
Buff lbuff[];
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int i=2,j=1000;
//---
   ArrayResize(lbuff,i);
   ArrayResize(lbuff[0].b,j);
   ArrayResize(lbuff[1].b,j);
  }
Rosh:
Jetez un coup d'œil à la section sur les opérations de surcharge, par exemple pour la classe CMatrix, cela vous conviendra peut-être.
Merci, je vais l'étudier.
 
Rosh:

Le fait est qu'un nombre réel est stocké en mémoire avec un maximum de 17 chiffres significatifs.

Essayez cet exemple pour sentir la différence :

La description dans l'aide sera corrigée.

Oui, Renat a déjà expliqué ci-dessus que Print() produit desdonnées de type double avec une précision de 4, et non de 16 chiffres décimaux après le point. C'était là tout le problème du point de vue de l'utilisateur.

 
Yedelkin:

Oui, Renat a déjà expliqué ci-dessus que Print() sort lesdonnées de type double à 4, et non à 16 chiffres décimaux après le point. C'était le problème du point de vue de l'utilisateur.

Non, Print() imprime au format %.16G, ce qui signifie qu'il essaiera d'imprimer un nombre avec un point et 16 chiffres significatifs. Dans ce cas, le nombre stocké est 199.99999999999997, qui comporte 17 chiffres significatifs (3 chiffres avant la virgule + 14 après la virgule). Lorsque j'essaie d'imprimer 16 chiffres, les arrondis commencent, 7 est arrondi à 10, on passe au chiffre supérieur, et 9 est là. Le principe du domino commence, le nombre imprimé est arrondi à 200.

Essayez un exemple :

void OnStart()
  {
   double a,b;

   a=7.0/200.0;
   b=7.0/a;
   Print("Print(b)=",b);
   Print("Print(DoubleToString(b,16))=",DoubleToString(b,16));
   double epsilon=MathPow(10,-13);
   Print("-------- После вычитания ",epsilon,"---------");
   b=b-epsilon;
   Print("Print(b)=",b);
   Print("Print(DoubleToString(b,16))=",DoubleToString(b,16));

   
  }

Regardez PrintFormat().

 
Rosh:

Non, Print() sort au format %.16G, ce qui signifie qu'il essaiera de sortir un nombre avec un point et 16 chiffres significatifs. Dans ce cas, le nombre stocké est 199.9999999999999997, qui comporte 17 chiffres significatifs (3 chiffres avant la virgule + 14 après la virgule). Lorsque j'essaie d'imprimer 16 chiffres, les arrondis commencent, 7 est arrondi à 10, on passe au chiffre supérieur, et 9 est là. Le principe du domino commence, le nombre imprimé est arrondi à 200.

Jetez un coup d'œil à PrintFormat().

Je comprends maintenant pourquoi nous nous concentrons sur le nombre de chiffres significatifs stockés.

...Mais si un nombre réel est stocké avec un maximum de 17 chiffres significatifs (dans notre cas, c'est 199,99999999999997), d'où viennent les chiffres significatifs ?

MP 0 victorg2 (EURUSD,M1) 11:04:42 Print(DoubleToString(b,16))=199.999999999999999716

? (J'ai compté 19 décharges)
 

"Dans les conditions de combat, le nombre de pi peut aller jusqu'à quatre".

DoubleToString fonctionne légèrement différemment du formatage dans l'imprimante (qui est laissé au CRT).

DoubleToString convertit les parties entières et fractionnaires en chaînes de caractères séparément et avec un algorithme légèrement plus rapide que le formatage standard.

Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
  • www.mql5.com
Основы языка / Типы данных / Вещественные типы (double, float) - Документация по MQL5
 
stringo:

Dans DoubleToString, les parties entières et fractionnaires sont converties en chaînes de caractères séparément et par un algorithme légèrement plus rapide que le formatage standard.

Mais il s'avère ensuite qu'un peu plus de 17 chiffres significatifs sont stockés en mémoire . Sinon, d'où viendraient les parties entières et fractionnaires pour les conversions en chaînes de caractères ? C'est-à-dire qu'indépendamment du fait que ce soit Print() ou DoubleToString(), ils obtiennent leurs données de quelque part (si nous parlons spécifiquement du stockage "en mémoire avec pas plus de 17 chiffres significatifs").

...Peut-être, bien sûr, que je me suis laissé emporter par l'expression "stockage en mémoire", et que je ne comprends pas bien en raison de mon ignorance de la nature du stockage des nombres réels.

 
Yedelkin:

Mais il s'avère ensuite qu'il y a un peu plus de 17 chiffres significatifs stockés en mémoire . Sinon, d'où viennent les parties entières et fractionnaires pour les conversions en chaînes de caractères ? Qu'il s'agisse de Print() ou de DoubleToString(), ils obtiennent leurs données de quelque part (si nous parlons spécifiquement de stockage "en mémoire avec pas plus de 17 chiffres significatifs").

...Peut-être, bien sûr, que j'ai été accroché à l'expression "stocker en mémoire", et que je ne comprends pas bien en raison de mon ignorance de la nature du stockage des nombres réels.

Parfois, jusqu'à 20 chiffres significatifs sont stockés, mais ce n'est pas garanti. Et en général, plus le nombre est grand dans la partie entière, moins il est précis dans la partie fractionnaire.

Pourquoi avez-vous besoin de 16 décimales ? Intérêt académique ?

Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
  • www.mql5.com
Основы языка / Типы данных / Вещественные типы (double, float) - Документация по MQL5
 
stringo:

Parfois, jusqu'à 20 chiffres significatifs sont stockés, mais ce n'est pas garanti. Et en général, plus le nombre est grand dans la partie entière, moins il est précis dans la partie fractionnaire.

Pourquoi avez-vous besoin de 16 décimales ? Intérêt académique ?

:) Afin de ne pas jouer au téléphone gâté, regardons l'histoire de fond.

Ici victorg a posé une question concernant le travail de la fonction Print() et les valeurs qu'elle produit.

Ici, je lui ai montré la raison.

Comme il ne voulait pas s'embêter avec les problèmes de la fonction Print(),

J'ai eu le culot de faire remarquer que la description de la fonction Print()indique que "les données de type double sont imprimées avec une précision de 16 chiffres décimaux après le point".En fait, il s'est avéréque la fonction Print() imprime des données quelque peu arrondies avec un exemple concret en annexe.

Une discussion animée s'ensuivit, à la fin personne ne fut capable de réfuter mon exemple, et Renat exposa la première version et dit que le livre de référence serait corrigé.

Quelques jours plus tard, Roche a présenté une deuxième version, où le chiffre 17 était mentionné.

Ayant rejoint la discussion, vous avez suggéré une troisième version, à savoir :"Dans DoubleToString, les parties entières et fractionnaires sont converties séparément en chaînes de caractères et par un algorithme légèrement plus rapide que le formatage standard" C'est-à-dire qu'il s'est déjà avéré que c'était une question de vitesse d'algorithme.

J'ai ensuite attiré votre attention sur le fait que, de manière générale, il était à peu près de la même taille que le numéro enregistré de la deuxième version de Roche.

stringo:

Pourquoi avez-vous besoin de 16 décimales ? Intérêt académique ?

Vous pouvez maintenant répondre à ces questions. J'ai donné un exemple où la fonction Print() produit des données arrondies. Je n'ai pas demandé les raisons d'un tel comportement. Mon exemple n'a pas été réfuté mais on m'a simplement conseillé d'utiliser une autre fonction et j'ai commencé à en expliquer les raisons. Et parmi ces explications, il y avait la mention de 16 (17) décimales. Comme tout n'était pas clair pour moi dans ces explications, j'ai posé des questions "au fur et à mesure". - Ce n'était donc même pas un intérêt académique de ma part, mais simplement un désir de comprendre ce que l'idée essayait de me transmettre.

 
Yedelkin:

. . . Ce n'est donc même pas un intérêt académique de ma part, mais simplement un désir de comprendre le message que j'essayais de faire passer.

Je ne pourrais pas être plus d'accord. L'intérêt académique n'a rien à voir avec cela.

Lire"nombre réel" dans la documentation. La norme IEEE 754, la table pour le double a 15 chiffres significatifs. Compte tenu de cela, il existe déjà quatre options - 15, 16, 17 chiffres significatifs et l'option où la partie entière et la partie fractionnaire sont stockées séparément. Mais ça ne marche pas comme ça ! Qu'est-ce que l'intérêt académique a à voir avec cela ? Il s'agit plutôt de logique formelle élémentaire, qui est d'ailleurs la base de ce langage de programmation.

Il me semble que le programmeur devrait écrire des programmes, et non enquêter sur le compilateur.

PS

J'aimerais profiter de cette occasion pour clarifier les choses :

Si j'augmente la taille d'un tableau dynamique à l'aide de la fonction ArrayResize(), est-il garanti que les données qui y étaient précédemment placées seront préservées ? Peut-être ce point devrait-il être explicitement mentionné dans la documentation (dans la description de la fonction ArrayResize()).Si quelqu'un le sait, merci de le conseiller.

 
victorg:

Si j'augmente la taille d'un tableau dynamique avec ArrayResize(), est-il garanti que les données qui y étaient précédemment placées seront préservées ? Peut-être ce point devrait-il être explicitement mentionné dans la documentation (dans la description de la fonction ArrayResize()).Si quelqu'un le sait, merci de le conseiller.

Ils le seront lorsque la taille sera augmentée, sinon une telle fonction n'a aucun intérêt.