绕过MQL4和MQL5中的Digits(),获取任何数字的小数位数(不仅仅是引号)。 - 页 7

 

根据Hubs上的一篇文章: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);
  }
//+------------------------------------------------------------------+

没有真正测试过,但似乎是有效的

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

根据Hubs上的一篇文章:https://habr.com/company/xakep/blog/257897/

没有真正测试过,但似乎是有效的

如果它给出了0.07的正确结果,那么它就能正确工作。

 
Alexey Viktorov:

如果它给出了0.07的正确结果,那么它就能正确工作。

不起作用 ((((

 
Igor Makanu:

不起作用 ((((

而且没有任何算法会起作用...

 
Alexey Viktorov:

而且没有任何算法会起作用...

将,但问题是在给定的精度和在权宜之计的大计算成本下,双精度的数量可以以任何格式重新计算:±sign-(1+mantissa/252)×2阶-1023

提取尾数和顺序很容易,但直接解决这个问题并不有趣。

 
Igor Makanu:

将,但问题是在给定的精度 和在权宜之计的大计算成本下,双精度的数量可以以任何格式重新计算:±sign-(1+mantissa/252)×2阶-1023

隔离尾数和顺序是很容易的,但正面解决这个问题并不有趣

如果准确度得到了,那么这整个事情就没有意义了。我已经举了一个例子,0.07有两个小数位。但如果你试图以编程方式计算数字,你会得到13个...而0.07不是计算的结果,而是手动输入的,甚至没有通过变量。

 

还有这个选项。

#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:

请清醒地认识到这一点。这是一派胡言,甚至不应该被认真讨论。

作者只是完全误解了双变量的内部运作。

О!

 
Alexandr Sokolov:
我没有声称知道所有的事情,最好告诉我什么是错的,或者让我看看你的版本

你想知道在你的程序中定义的每个双数类型的变量有多少个小数位。这就是胡说八道。所有double类型的变量都有相同的表示方法。它们被表示为Float -浮点。有时该点在左边,有时在右边--这取决于数字的价值。100万和100万分之一以不同的精度表示。

 
Konstantin Gruzdev:

还有这样一种变体。

不,这行不通,我昨天通过类型转换做到了,这是脚本,你的例子和我的。

#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));
  }

结果。

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

2018.11.13 01:49:16.131 tst (EURUSD,M30) 1.Digit() = 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.Digit() = 3



你可以谷歌一下FP-Printing-PLDI96.pdf,但我怀疑有人会按照算法来做所有的事情。