Como posso verificar se o conteúdo de uma variável é numérico? - página 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);
  }  
//+------------------------------------------------------------------+
Obrigado por seus códigos de exemplo. Mas sua palavra-chave "IsNumeric" não parece pertencer à MQL4. Por favor, me corrija se eu estiver errado. No entanto, seu código está funcionando muito bem e este é um exemplo perfeito do que eu tenho procurado. Obrigado.
 
macpee Mas sua palavra-chave "IsNumeric" não parece pertencer à MQL4. Por favor, me corrija se eu estiver errado.
Não é uma palavra-chave, é uma função que ele forneceu acima.
 
whroeder1:
Não é uma palavra-chave, é uma função que ele forneceu acima.
Oh, olhe para mim. Eu deveria ter sabido. Obrigado @whroeder1.
 
macpee:
Oh, olhe para mim. Eu deveria ter sabido. Obrigado @whroeder1.
Claro que um período (.) deve ser numérico, pois (.) é considerado como a mesma coisa com um período e zero (.0) que na verdade é zero (0). Agora eu tentei aumentar o número de períodos (.....) e ainda o reconheço como numérico. Precisamos do código de período (.) para eliminar o período adicional (....) uma vez que o primeiro período foi citado em
if((char1>47 && char1<58) || char1==46)
A propósito, não consigo encontrar a lista do código (ASCII, presumo eu).

Outra coisa é como inserir números negativos. O código precisa capturar o sinal de negação (-) somente no início da entrada.

Além disso, a fim de aperfeiçoar o código. Ele precisa aceitar o símbolo de negação (-) mesmo no meio de números como (45-20) e tratá-lo como subtração e avaliar e então usar o código
int char1=StringGetChar(text,i);
para verificar se o resultado é numérico. Podemos fazer isto para todas as quatro operações binárias básicas. Mas isso não é importante para nós agora.

A idéia é fazer OBJPROP_TEXT propriedade da OBT_EDIT para aceitar dados do calendário econômico e tratá-los como os números que são. É por isso que uma função embutida do IsNumeric é bastante importante para evitar escrever um código desnecessariamente grande para ele.
 
macpee:
É claro que um período (.) deve ser numérico já que (.) é considerado como a mesma coisa com um período e zero (.0) que na verdade é zero (0). Agora eu tentei aumentar o número de períodos (.....) e ainda o reconheço como numérico. Precisamos do código para período (.) de modo a eliminar período adicional (....) uma vez que o primeiro período foi citado em
if((char1>47 && char1<58) || char1==46)
A propósito, não consigo encontrar a lista do código (ASCII, presumo eu).

Outra coisa é como inserir números negativos. O código precisa capturar o sinal de negação (-) somente no início da entrada.

Além disso, a fim de aperfeiçoar o código. Ele precisa aceitar o símbolo de negação (-) mesmo no meio de números como (45-20) e tratá-lo como subtração e avaliar e então usar o código
int char1=StringGetChar(text,i);
para verificar se o resultado é numérico. Podemos fazer isto para todas as quatro operações binárias básicas. Mas isso não é importante para nós agora.

A idéia é fazer OBJPROP_TEXT propriedade da OBT_EDIT para aceitar dados do calendário econômico e tratá-los como os números que são. É por isso que uma função embutida do IsNumeric é bastante importante para evitar escrever um código desnecessariamente grande para ele.
Ou talvez uma solução seja converter a string para o dobro após a verificação do 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

Outra coisa é como inserir números negativos. O código precisa capturar o sinal de negação (-) somente no início da entrada.

Há algum eco aqui dentro?

honest_knave:

Sim, esse tipo de coisa.

Você precisaria ter cuidado:

  • Múltiplos pontos decimais (passariam mas não deveriam passar)
  • Uso de símbolos + e - (não passaria mas deveria)
  • Uso de , ou como separador de milhares, ou como ponto decimal (não passaria mas deveria passar)
  • Um ponto decimal solitário, sem outros caracteres (passaria mas não deveria)
  • Números além da capacidade do elenco
  • Espaços

________________________________

macpee:

A propósito, não consigo encontrar a lista do código (ASCII, presumo).

Vá em frente, experimente. Eu sei que você está ansioso por uma chance de aprimorar suas habilidades de busca.

________________________________

macpee:

A idéia é fazer OBJPROP_TEXT propriedade de OBT_EDIT para aceitar os dados do calendário econômico e tratá-los como os números que eles são. É por isso que uma função embutida do IsNumeric é bastante importante para evitar escrever um código desnecessariamente grande para ele.

Embora eu possa ter entendido mal sua intenção, se você quiser que o usuário insira datas em uma caixa de edição e depois as interprete como datas (possivelmente não se você estiver interessado em números negativos), eu não estou convencido de que esta seja a melhor abordagem por uma série de razões.

 
honest_knave:

Há algum eco aqui?

________________________________

Vá em frente, experimente. Eu sei que você está ansioso por uma chance de aprimorar suas habilidades de busca.

________________________________

Embora eu possa ter entendido mal sua intenção, se você quiser que o usuário insira datas em uma caixa de texto e depois as interprete como datas (possivelmente não se você estiver interessado em números negativos), eu não estou convencido de que esta seja a melhor abordagem por uma série de razões.

Na verdade, os dados econômicos em questão não incluem datas - apenas dados 'reais', 'previstos', 'anteriores' e possivelmente 'revisados'. É claro que também não pretendemos inserir símbolos como B(para bilhões), %(para porcentagem), etc. Apenas números reais puros, sem espaços. A idéia é calcular o que eu chamo de "Índice de Lançamento Simultâneo". O objetivo é combinar um conjunto de dados econômicos lançados simultaneamente e vê-los como um único dado. Eu combinaria todos os 'reais' como um 'real', todas as 'previsões' como uma 'previsão', etc., a fim de ver a relação entre o combinado 'real' e o combinado 'previsão', etc.

 
macpee:
if((char1>47 && char1<58) || char1==46)
A propósito, não consigo encontrar a lista do código (ASCII, presumo eu).
Não faça números de código difíceis. Faça seu código se autodocumentar.
if((char1>='0' && char1<='9') || char1=='.')
Constantes de caracteres - Tipos de números inteiros - Tipos de dados - Noções básicas de linguagem - Referência MQL4
 
macpee:
Na verdade, os dados econômicos em questão não incluem datas - apenas dados 'reais', 'previstos', 'anteriores' e possivelmente 'revisados'. É claro que também não pretendemos inserir símbolos como B(para bilhões), %(para porcentagem), etc. Apenas números reais puros, sem espaços. A idéia é calcular o que eu chamo de "Índice de Lançamento Simultâneo". O objetivo é combinar um conjunto de dados econômicos lançados simultaneamente e vê-los como um único dado. Eu combinaria todos os 'reais' como um 'real', todas as 'previsões' como uma 'previsão', etc., a fim de ver a relação entre o combinado 'real' e o combinado 'previsão', etc.

Portanto:

  • Passe o fio por referência
  • Tirar os espaços em branco
  • Tire o ','
  • Verifique se '+' ou '-' aparece apenas como o primeiro caracter
  • Verifique se todos os outros caracteres são um número entre 0 e 9

por exemplo

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

Se voltar a ser verdade, você pode lançar o cordel como um número.

 
honest_knave:

Portanto:

  • Passe o fio por referência
  • Tirar os espaços em branco
  • Tire o ','
  • Verifique se há apenas um '.
  • Verifique se '+' ou '-' aparece apenas como o primeiro caracter
  • Verifique se todos os outros caracteres são um número entre 0 e 9

por exemplo

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

Se voltar a ser verdade, você pode lançar o cordel como um número.

Você realmente gosta da complicação . Se o objetivo é apenas processar números reais, use StringToDouble() e um processamento de caso especial 0.