Как проверить, является ли содержимое переменной числовым? - страница 3

 
Ernst Van Der Merwe:
void OnStart()
  {
//---
   ObjectCreate("SimultaneousReleaseIndex1",OBJ_LABEL,0,0,0);
   ObjectSetString(0,"SimultaneousReleaseIndex1",OBJPROP_TEXT,"Four");
   ObjectCreate("SimultaneousReleaseIndex2",OBJ_LABEL,0,0,0);
   ObjectSetString(0,"SimultaneousReleaseIndex2",OBJPROP_TEXT,"44");
   ObjectCreate("SimultaneousReleaseIndex3",OBJ_LABEL,0,0,0);
   ObjectSetString(0,"SimultaneousReleaseIndex3",OBJPROP_TEXT,"Forty4");
   ObjectCreate("SimultaneousReleaseIndex4",OBJ_LABEL,0,0,0);
   ObjectSetString(0,"SimultaneousReleaseIndex4",OBJPROP_TEXT,".1234567890");
  
   if(IsNumeric(ObjectGetString(0,"SimultaneousReleaseIndex1",OBJPROP_TEXT)))
      Print("text1 is numeric");
   if(IsNumeric(ObjectGetString(0,"SimultaneousReleaseIndex2",OBJPROP_TEXT)))
      Print("text2 is numeric");
   if(IsNumeric(ObjectGetString(0,"SimultaneousReleaseIndex3",OBJPROP_TEXT)))
      Print("text3 is numeric");
   if(IsNumeric(ObjectGetString(0,"SimultaneousReleaseIndex4",OBJPROP_TEXT)))
      Print("text4 is numeric");
  }
//---
bool IsNumeric(string text)
  {
   int length=StringLen(text);
   for(int i=0;i<length;i++)
     {
      int char1=StringGetChar(text,i);
      if((char1>47 && char1<58) || char1==46)
         continue;
      else
         return(false);
     }
   return(true);
  }  
//+------------------------------------------------------------------+
Спасибо за ваши примеры кодов. Но ваше ключевое слово "IsNumeric", похоже, не относится к MQL4. Пожалуйста, поправьте меня, если я ошибаюсь. Тем не менее, ваш код работает очень хорошо, и это прекрасный пример того, что я искал. Спасибо.
 
macpee Но ваше ключевое слово "IsNumeric", похоже, не принадлежит MQL4. Пожалуйста, поправьте меня, если я ошибаюсь.
Это не ключевое слово, это функция, которую он предоставил выше.
 
whroeder1:
Это не ключевое слово, это функция, которую он предоставил выше.
О, посмотрите на меня. Я должен был догадаться. Спасибо @whroeder1.
 
macpee:
О, посмотрите на меня. Я должен был догадаться. Спасибо @whroeder1.
Конечно, точка (.) должна быть числовой, поскольку (.) рассматривается как одно и то же с точкой и нулем (.0), который на самом деле является нулем (0). Теперь я попробовал увеличить количество периодов (.....), но он все равно распознает их как числовые. Нам нужен код для точки (.), чтобы исключить дополнительную точку (....) после того, как первая точка была приведена.
if((char1>47 && char1<58) || char1==46)
Кстати, я не могу найти список кодов (ASCII, я полагаю).

Еще один момент - как вводить отрицательные числа. Код должен фиксировать знак отрицания (-) только в начале ввода.

Более того, чтобы усовершенствовать код. Он должен принимать знак отрицания (-) даже в середине чисел, таких как (45-20), и рассматривать его как вычитание, оценивать, а затем использовать код
int char1=StringGetChar(text,i);
для проверки того, что результат является числовым. Мы можем сделать это для всех четырех основных двоичных операций. Но сейчас это для нас не важно.

Вся идея в том, чтобы заставить свойство OBJPROP_TEXT в OBT_EDIT принимать данные экономического календаря и обрабатывать их как числа, которыми они и являются. Поэтому встроенная функция IsNumeric очень важна, чтобы избежать написания неоправданно большого кода для нее.
 
macpee:
Конечно, точка (.) должна быть числовой, поскольку (.) рассматривается как одно и то же с точкой и нулем (.0), который на самом деле является нулем (0). Теперь я попробовал увеличить количество периодов (.....), и он все равно распознает его как числовой. Нам нужен код для периода (.), чтобы исключить дополнительный период (....) после того, как первый период был приведен.
if((char1>47 && char1<58) || char1==46)
Кстати, я не могу найти список кодов (ASCII, я полагаю).

Еще один момент - как вводить отрицательные числа. Код должен фиксировать знак отрицания (-) только в начале ввода.

Более того, чтобы усовершенствовать код. Он должен принимать знак отрицания (-) даже в середине чисел, таких как (45-20), и рассматривать его как вычитание и оценивать, а затем использовать код
int char1=StringGetChar(text,i);
для проверки того, что результат является числовым. Мы можем сделать это для всех четырех основных двоичных операций. Но сейчас это для нас не важно.

Вся идея в том, чтобы заставить свойство OBJPROP_TEXT в OBT_EDIT принимать данные экономического календаря и обрабатывать их как числа, которыми они и являются. Поэтому встроенная функция IsNumeric очень важна, чтобы избежать написания неоправданно большого кода для нее.
Или же решением может быть преобразование строки в двойное число после проверки IsNumeric.
 

macpee:
Of course a period (.) should be numeric since (.) is regarded as the same thing with a period and zero (.0) which is in fact zero (0). Now I tried increasing the number of period (.....) and it is still recognizing it as numeric. We need the code for period (.) so as to eliminate additional period (....) once the first period has been cited in

Другое дело - как вводить отрицательные числа. Код должен фиксировать знак отрицания (-) только в начале ввода.

Есть ли здесь эхо?

honest_knave:

Да, что-то вроде этого.

Вам нужно быть осторожным в отношении:

  • Множественные десятичные точки (пройдут, но не должны)
  • Использование символов + и - (не пройдет, но должно пройти)
  • Использование символа , как разделителя тысяч или как десятичной точки (не пройдет, но должно пройти).
  • Одиночная десятичная точка без других символов (пройдет, но не должна)
  • Числа, превышающие возможности актеров
  • Пробелы

________________________________

macpee:

Кстати, я не могу найти список кода (ASCII, я предполагаю).

Давайте, попробуйте. Я знаю, что вам давно хотелось отточить свои навыки поиска.

________________________________

macpee:

Вся идея в том, чтобы заставить свойство OBJPROP_TEXT в OBT_EDIT принимать данные экономического календаря и рассматривать их как числа, которыми они и являются. Поэтому встроенная функция IsNumeric очень важна, чтобы избежать написания неоправданно большого кода для нее.

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

 
honest_knave:

Есть ли здесь эхо?

________________________________

Давай, попробуй. Я знаю, что ты давно жаждал возможности отточить свои навыки поиска.

________________________________

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

На самом деле рассматриваемые экономические данные не содержат дат - только "фактические", "прогнозные", "предыдущие" и, возможно, "пересмотренные" данные. Конечно, мы также не собираемся вводить символы, такие как B(для миллиарда), %(для процента) и т.д. Только чистые реальные числа без пробелов. Идея заключается в том, чтобы рассчитать то, что я называю "Индекс одновременного выпуска". Он предназначен для того, чтобы объединить набор экономических данных, выпущенных одновременно, и рассматривать их как единое целое. Я бы объединил все "факты" как один "факт", все "прогнозы" как один "прогноз" и т.д., чтобы увидеть взаимосвязь между объединенным "фактом" и объединенным "прогнозом" и т.д.

 
macpee:
if((char1>47 && char1<58) || char1==46)
Кстати, я не могу найти список кода (ASCII, я полагаю).
Не надо жестко кодировать числа. Сделайте свой код самодокументирующимся.
if((char1>='0' && char1<='9') || char1=='.')
Символьные константы - Целочисленные типы - Типы данных - Основы языка - Справочник по MQL4
 
macpee:
На самом деле рассматриваемые экономические данные не включают даты - только "фактические", "прогнозные", "предыдущие" и, возможно, "пересмотренные" данные. Конечно, мы также не собираемся вводить такие символы, как B(для миллиарда), %(для процента) и т. д. Только чистые реальные числа без пробелов. Идея заключается в том, чтобы рассчитать то, что я называю "Индекс одновременного выпуска". Он предназначен для того, чтобы объединить набор экономических данных, выпущенных одновременно, и рассматривать их как единое целое. Я бы объединил все "факты" как один "факт", все "прогнозы" как один "прогноз" и т.д., чтобы увидеть взаимосвязь между объединенными "фактами" и объединенными "прогнозами" и т.д.

Итак:

  • Передайте строку по ссылке
  • Вычеркните пробелы
  • Вычеркните ','
  • Проверьте, что '+' или '-' появляются только в качестве первого символа.
  • Проверьте, что каждый второй символ - это число от 0 до 9.

например.

bool IsValidNumber(string &text)
  {
   StringReplace(text," ",NULL);
   StringReplace(text,",",NULL);
   int point_cnt = 0;
   for(int i=StringLen(text)-1; i>=0; i--)
     {
      int this_char = StringGetChar(text,i);
      if(this_char == '.')
        {
         point_cnt++;
         if(point_cnt>1)       return(false);
         if(StringLen(text)<2) return(false);
        }
      else if(this_char == '+' || this_char == '-')
        {
         if(i>0) return(false);
        }
      else if(this_char < '0' || this_char > '9') return(false);
     }
   return(true);
  }

Если возвращается true, то строку можно преобразовать в число.

 
honest_knave:

Итак:

  • Передайте строку по ссылке
  • Вычеркните пробелы
  • Вычеркните ','
  • Проверьте, что есть только один символ '.'
  • Проверьте, что '+' или '-' появляются только в качестве первого символа.
  • Проверьте, что каждый второй символ - это число от 0 до 9.

например.

bool IsValidNumber(string &text)
  {
   StringReplace(text," ",NULL);
   StringReplace(text,",",NULL);
   int point_cnt = 0;
   for(int i=StringLen(text)-1; i>=0; i--)
     {
      int this_char = StringGetChar(text,i);
      if(this_char == '.')
        {
         point_cnt++;
         if(point_cnt>1)       return(false);
         if(StringLen(text)<2) return(false);
        }
      else if(this_char == '+' || this_char == '-')
        {
         if(i>0) return(false);
        }
      else if(this_char < '0' || this_char > '9') return(false);
     }
   return(true);
  }

Если возвращается true, можно преобразовать строку в число.

Вы действительно любите усложнения . Если цель - просто обработать вещественные числа, используйте StringToDouble() и обработку специального случая 0.