Как выделить число из сложносоставной строки? - страница 6

 
Renat Akhtyamov #:

не могу понять, что у меня не так?

Нужно кэшировать значение GetLastError():

int nError = GetLastError();
if (nError != 0)
{
      Print("ERROR:"+IntegerToString(nError));
      ResetLastError();
}
 
Ihor Herasko #:

Нужно кэшировать значение GetLastError():

прекрасно работает!

спасибо!

Сейчас вижу номер ошибки.

Считаю что очень полезно вставлять эту приблуду в самом конце программы.

Ну чтобы не молчала.

Однажды я 10 минут на реале ждал когда сделка откроется.

Голову сломал - почему не работает....

 
Renat Akhtyamov #:

да там ловить нечо

я так же пишу как и Вы

ну нравится Алексею по своему, ну и пусть пишет

дело хозяйское

Я не спорил, я просто пытался понять почему фломастеры только на цвет разные, а на вкус все одинаковые.

 
Alexey Viktorov #:

Я не спорил, я просто пытался понять почему фломастеры только на цвет разные, а на вкус все одинаковые.

ты так думаешь?

мне кажется что они все таки будут разные по вкусу

 

внесу свои пять копеек. 
Такой вариант парсит строку и вытаскивает из него массив double. Пробелы игнорируются. Распознает такие форматы: .001;  -.076; -1.788; 8989.8899; 789; 0

За счет того, что не  используется штатная StringToDouble (или double(string)), а используется собственный алгоритм (в функции IsNextNumber()), получается выйгрыш в производительности примерно в 2-3 раза. 

bool IsNextNumber(string &s, int &i, double &d) {
   static const double dec[20] = {1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13,1e14,1e15,1e16,1e17,1e18,1e19};
   uchar c = uchar(s[i++]);
   while(c==32) c = uchar(s[i++]);
   bool is_num = (c<='9'&& c>='0');
   if (is_num || c=='-' || c=='.') {
      int j = 0;
      int p = (c=='.') ? 0 : -1;
      bool is_not_null = is_num;
      ulong mantissa = is_num ? c-48 : 0;
      bool minus = (c=='-');
      while(true) {
         c = uchar(s[i++]);
         while(c==32) c = uchar(s[i++]);
         j++;
         if(c=='.') {
            if (p<0) p=j;
            else break;
         } else if (c<='9'&& c>='0') {
            is_not_null = true;
            mantissa = mantissa*10 + c - 48;
         } else break;
      }
      if (is_not_null) {
         d = (double)mantissa;
         if (minus) d = - d;
         if(p>=0) {
            p=j-p-1;
            d/=dec[p];
         }
         i--;
         return true;
      }
   }
   i--;
   return false;
}

////////////////////////////////////////////////////////////////////////////////////////////
int GetDoubleArrayFromString(string Str, double &d[]) {
   const int Size = StringLen(Str) - 1;
   double Res = 0;
   int size = 0;

   for (int i = 0; i <= Size; i++) {
      if (IsNextNumber(Str,i,Res)) {
         size++;
         ArrayResize(d,size);
         d[size-1] = Res;
      }
   }
   return(size);
}
2023.12.22 01:23:53.450 TestStringParseToDoubleArray (EURUSD,M15)       Sum = 815825.77262001
2023.12.22 01:23:53.451 TestStringParseToDoubleArray (EURUSD,M15)        10000 иттераций за 902 μs, StringToDouble, контрольная сумма = 815825.7726200103
2023.12.22 01:23:53.452 TestStringParseToDoubleArray (EURUSD,M15)        10000 иттераций за 981 μs, GetDouble, контрольная сумма = 815825.7726200103
2023.12.22 01:23:53.452 TestStringParseToDoubleArray (EURUSD,M15)        10000 иттераций за 247 μs, fast mode, контрольная сумма = 815825.7726200103
2023.12.22 01:23:53.453 TestStringParseToDoubleArray (EURUSD,M15)        1000 иттераций за 788 μs, fast mode array, контрольная сумма = 815825.7726200103
2023.12.22 01:23:53.455 TestStringParseToDoubleArray (EURUSD,M15)        1000 иттераций за 1858 μs, GetDouble2 array, контрольная сумма = 815825.7726200103
2023.12.22 01:23:58.105 TestStringParseToDoubleArray (EURUSD,M15)       Sum = -800648.84093000
2023.12.22 01:23:58.106 TestStringParseToDoubleArray (EURUSD,M15)        10000 иттераций за 913 μs, StringToDouble, контрольная сумма = -800648.8409300013
2023.12.22 01:23:58.107 TestStringParseToDoubleArray (EURUSD,M15)        10000 иттераций за 1048 μs, GetDouble, контрольная сумма = -800648.8409300013
2023.12.22 01:23:58.107 TestStringParseToDoubleArray (EURUSD,M15)        10000 иттераций за 239 μs, fast mode, контрольная сумма = -800648.8409300013
2023.12.22 01:23:58.108 TestStringParseToDoubleArray (EURUSD,M15)        1000 иттераций за 815 μs, fast mode array, контрольная сумма = -800648.8409300013
2023.12.22 01:23:58.110 TestStringParseToDoubleArray (EURUSD,M15)        1000 иттераций за 1850 μs, GetDouble2 array, контрольная сумма = -800648.8409300013
Файлы:
 
Nikolai Semko #:

Распознает такие форматы: .001;  -.076; -1.788; 8989.8899; 789; 0

Если нужны неотрицательные числа, начинающиеся с точки.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Как выделить число из сложносоставной строки?

fxsaber, 2023.12.21 09:01

bool IsNumber( const ushort Char )
{
  return((Char >= '0') && (Char <= '9'));
}

double GetDouble( const string Str )
{
  const int Size = StringLen(Str) - 1;
  double Res = 0;
  
  for (int i = 0; i <= Size; i++)
    if (IsNumber(Str[i]) ||
        (((Str[i] == '-') || (Str[i] == '.')) && (i < Size) && IsNumber(Str[i + 1])))
    {
      Res = (double)StringSubstr(Str, i);
      
      break;
    }    
  
  return(Res);
}
 
Nikolai Semko #:

внесу свои пять копеек. 
Такой вариант парсит строку и вытаскивает из него массив double. Пробелы игнорируются. Распознает такие форматы: .001;  -.076; -1.788; 8989.8899; 789; 0

За счет того, что не  используется штатная StringToDouble (или double(string)), а используется собственный алгоритм (в функции IsNextNumber()), получается выйгрыш в производительности примерно в 2-3 раза. 

Похоже это почти идеальное решение для парсинга любых чисел и любого числа этих чисел в строке. То что  успел протестировать работает идеально в большинстве вариаций, (если не считать игнор пробелов и еще некоторых моментов возможно с этим связанных).  Для полноценной функции парсинга нужно будет только немного доработать анализ массива, чтобы функция могла работать и со строками, где нет чисел и где количество этих чисел неизвестно. Но это уже всегда можно обработать на свой вкус и цвет.  

p.s. единственное... почти до слез обидно, что этот код я наверное еще не скоро начну понимать
я и предыдущие примеры с трудом разбирал ;(

 
Nikolai Semko #:
внесу свои пять копеек

Это надо в ветку особенностей

 
leon_17 #:

Похоже это почти идеальное решение для парсинга любых чисел и любого числа этих чисел в строке. То что  успел протестировать работает идеально в большинстве вариаций, (если не считать игнор пробелов и еще некоторых моментов возможно с этим связанных).  Для полноценной функции парсинга нужно будет только немного доработать анализ массива, чтобы функция могла работать и со строками, где нет чисел и где количество этих чисел неизвестно. Но это уже всегда можно обработать на свой вкус и цвет.  

p.s. единственное... почти до слез обидно, что этот код я наверное еще не скоро начну понимать
я и предыдущие примеры с трудом разбирал ;(

Для чуть лучшего понимания можете заменить 32 на ' ', а 48 на '0'.

 
JRandomTrader #:

Для чуть лучшего понимания можете заменить 32 на ' ', а 48 на '0'.

Ну, да, чуть-чуть понятнее... совсем чуть-чуть )

Кто понимает этот код, помогите избавиться от ошибки 5041 ( Позиция за пределами строки ) после исполнения этой функции.
Только, что обнаружил.

Причина обращения: