Obter o número de casas decimais de quaisquer números (não apenas citações) contornando Dígitos() em MQL4 e MQL5 - página 7

 

com base em um artigo sobre os centros:https://habr.com/company/xakep/blog/257897/

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   double a=1.123456;
   Print(DoubleToDigits(a));
  }
//+------------------------------------------------------------------+
int DoubleToDigits(double value)
  {
   const double digits[18]={1 e17,1 e16,1 e15,1 e14,1 e13,1 e12,1 e11,1 e10,1 e9,1 e8,1 e7,1 e6,1 e5,1 e4,1 e3,1 e2,1 e1,1.0};
   double absvalue=fabs(value);
   int i,decimal=(int)absvalue;
   double real=floor((absvalue-decimal)*1 e18+0.5)-0.5;
   double normalize=fmod(real,1 e3);
   if(normalize>0.0)
     {
      if(normalize>51.5) real+=1 e3-normalize; else real-=normalize;
     }
   double res,last=0.0;
   for(i=0;i<18;i++)
     {
      res=real-fmod(real,digits[i]);
      if(last-res>=0.0) break; else last=res;
     }
   return(i);
  }
//+------------------------------------------------------------------+

não foi realmente testado, mas parece funcionar

Всё, точка, приплыли! Учимся работать с числами с плавающей точкой и разрабатываем альтернативу с фиксированной точностью десятичной дроби
Всё, точка, приплыли! Учимся работать с числами с плавающей точкой и разрабатываем альтернативу с фиксированной точностью десятичной дроби
  • habr.com
Сегодня мы поговорим о вещественных числах. Точнее, о представлении их процессором при вычислении дробных величин. Каждый из нас сталкивался с выводом в строку чисел вида 3,4999990123 вместо 3,5 или, того хуже, огромной разницей после вычислений между результатом теоретическим и тем, что получилось в результате выполнения программного кода...
 
Igor Makanu:

com base em um artigo sobre os centros:https://habr.com/company/xakep/blog/257897/

não foi realmente testado, mas parece funcionar

Se der o resultado correto de 0,07, então ele funciona corretamente.

 
Alexey Viktorov:

Se der o resultado correto de 0,07, então ele funciona corretamente.

não funciona ((((

 
Igor Makanu:

não funciona ((((

E nenhum algoritmo funcionará...

 
Alexey Viktorov:

E nenhum algoritmo funcionará...

será, mas o problema está na precisão dada e na conveniência de grandes custos computacionais, o número de dupla precisão pode ser recalculado em qualquer formato:±sign - (1+mantissa/252) × 2 pedido- 1023

É fácil extrair a mantissa e o pedido, mas não é interessante resolver este problema diretamente.

 
Igor Makanu:

será, mas o problema está na precisão dada e na conveniência de grandes custos computacionais, o número de dupla precisão pode ser recalculado em qualquer formato:±sign - (1+mantissa/252) × 2 pedido- 1023

É fácil isolar a mantissa e o pedido, mas não é interessante resolver este problema de frente

Se a precisão for dada, então tudo isto não faz sentido. Eu já dei um exemplo, 0,07 tem duas casas decimais. Mas se você tentar calcular o número de dígitos de forma programática, você receberá treze. E 0,07 não é o resultado de cálculos, mas é inserido manualmente, nem mesmo através de uma variável.

 

Há também esta opção:

#define  EPSILON   0.000000001
#define  MORE(A,B) ((A)-(B)>EPSILON)

int Digits(double value)
  {
   int digits=0;
   while(MORE(1.0/MathPow(10,digits),value)) 
      digits++;
   return(digits);
  }
 
Mesaoria:

Recupere seus sentidos. Isso é um absurdo que nem deveria ser discutido seriamente.

O autor simplesmente tem um total equívoco sobre o funcionamento interno de variáveis duplas.

О!

 
Alexandr Sokolov:
Eu não disse que sabia tudo, é melhor me dizer o que estava errado ou me mostrar sua versão

Você quer saber quantas casas decimais cada variável do tipo duplo é definida em seu programa. Este é o absurdo. Todas as variáveis do tipo duplo têm a mesma representação. Eles são representados como Float - ponto flutuante. Às vezes a questão é para a esquerda, às vezes para a direita - depende do valor do número. Um milhão e um milionésimo estão representados com precisão diferente.

 
Konstantin Gruzdev:

Existe também uma variante desse tipo:

Não, não vai funcionar, eu fiz isso ontem via conversão de tipo, aqui está o roteiro, seu exemplo e o meu:

#define  EPSILON   0.000000001
#define  MORE(A,B) ((A)-(B)>EPSILON)

int Digit(double value)
  {
   int digits=0;
   while(MORE(1.0/MathPow(10,digits),value)) 
      digits++;
   return(digits);
  }
//+------------------------------------------------------------------+
int DoubleToDigits(double value)
 {
   double absvalue=NormalizeDouble(fabs(value-int(value)),15);
   int res=StringLen(string(absvalue))-2;
   return(res<=0?0:res);
 }
//+------------------------------------------------------------------+
void OnStart()
  {
   double f = 122334550.007;
   Print("1. DoubleToDigits() = ",DoubleToDigits(f));
   Print("1. Digit() = ",Digit(f));
   f = 0.007;
   Print("2. DoubleToDigits() = ",DoubleToDigits(f));
   Print("2. Digit() = ",Digit(f));
  }

resultados:

2018.11.13 01:49:16.131 tst (EURUSD,M30) 1. DoubleToDigits() = 11

2018.11.13 01:49:16.131 tst (EURUSD,M30) 1. Dígito() = 0

2018.11.13 01:49:16.131 tst (EURUSD,M30) 2. DoubleToDigits() = 3

2018.11.13 01:49:16.131 tst (EURUSD,M30) 2. Dígito() = 3



você pode ir ao GoogleFP-Printing-PLDI96.pdf, mas duvido que alguém faça tudo de acordo com o algoritmo