isString(), isNumeric()

Vous avez une idée pour améliorer ou modifier PureBasic ? N'hésitez pas à la proposer.
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: isString(), isNumeric()

Message par graph100 »

Je vous suit sur l'aspect utilisateur. Il faut juste apprendre à le différencier correctement.

Maintenant pour les moments ou le programmateur ne connait pas le type d'un paramètre (je ne dirais pas une variable), ça arrive dans la mesure ou on prévoit un outil (fonction, DLL etc..) qui a un nombre de paramètre définis et qui lance la même routine derrière.

Or actuellement il n'est pas possible d'écrire une procédure avec des paramètres dont le type n'est pas défini, ou pourrait changer.
En revanche les type numériques sont automatiquement convertis dans le type demandé, ce qui est pratique, mais pas rigoureux.

Il faudrait pouvoir surcharger les définitions de procédure pour que TypeOf prenne une utilité plus importante !
J'ai essayé de faire un exemple ci-dessus, mais je suis pas un pro de la macro ( :wink: PAPIPP)

Sachant que pour des raisons de taille et d'efficacité de code, il vaudrait mieux utiliser CompilerSelect que Select

Code : Tout sélectionner

Macro Affiche(param)
	Select TypeOf(param)
		Case #PB_String
			Affiche_STR(PeekS(@param))
			
		Case #PB_Quad
			Affiche_Num(PeekQ(@param))
			
		Case #PB_Long
			Affiche_Num(PeekL(@param))
			
		Case #PB_Double
			Affiche_flottant(PeekD(@param))
			
		Case #PB_Float
			Affiche_flottant(PeekF(@param))
			
	EndSelect
EndMacro


Procedure Affiche_STR(str.s)
	
	MessageRequester("titre", str)
	
EndProcedure

Procedure Affiche_Num(num.q)
	
	MessageRequester("titre", Str(num))
	
EndProcedure

Procedure Affiche_flottant(flottant.d)

	MessageRequester("titre", StrD(flottant, 4))
	
EndProcedure


var_str.s = "5831"
Affiche(var_str)

var_num.l = 466
Affiche(var_num)

var_flottant.f = 48.633
Affiche(var_flottant)

_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
G-Rom
Messages : 3627
Inscription : dim. 10/janv./2010 5:29

Re: isString(), isNumeric()

Message par G-Rom »

pour répondre au sujet du post, j'avais écris un parser asm, j'utilisais les regex, très pratique :

Code : Tout sélectionner

Procedure.s packString(string.s, separator.s) 
  Protected Chaine$,Chaine2$
  Chaine$=Trim(string)
  Repeat
    Chaine2$=Chaine$
    Chaine$ = ReplaceString(Chaine$, separator+separator, separator)
  Until Chaine2$=Chaine$
  ProcedureReturn Chaine$
EndProcedure

; /////////////////////////////////////////////////////////////////////////////
; FORMAT 0x??...
; /////////////////////////////////////////////////////////////////////////////
Procedure.a isHexaDecimal(word$)
For i = 3 To Len(word$)  
  EXPREG$ + "[0-9 A-F a-f]"
Next 
RE = CreateRegularExpression(#PB_Any, "^0X"+EXPREG$)
If RE
   Result.a = MatchRegularExpression(RE, word$)
   FreeRegularExpression(RE)  
EndIf 
ProcedureReturn Result
EndProcedure

; /////////////////////////////////////////////////////////////////////////////
; FORMAT $xx...
; /////////////////////////////////////////////////////////////////////////////
Procedure.a isHexaDecimal2(word$)
For i = 2 To Len(word$)  
  EXPREG$ + "[0-9 A-F a-f]"
Next 
RE = CreateRegularExpression(#PB_Any, "^$"+EXPREG$)
If RE
   Result.a = MatchRegularExpression(RE, word$)
   FreeRegularExpression(RE)  
EndIf 
ProcedureReturn Result
EndProcedure

; /////////////////////////////////////////////////////////////////////////////
; FORMAT [0 to 9]...
; /////////////////////////////////////////////////////////////////////////////
Procedure.a isDigit(word$)
For i = 1 To Len(word$)  
  EXPREG$ + "[0-9]"
Next 
RE = CreateRegularExpression(#PB_Any,EXPREG$)
If RE
   Result.a = MatchRegularExpression(RE, word$)
   FreeRegularExpression(RE)  
EndIf 
ProcedureReturn Result
EndProcedure

; /////////////////////////////////////////////////////////////////////////////
; FORMAT : LABEL: / LABEL_0: etc...
; /////////////////////////////////////////////////////////////////////////////
Procedure.a isLabel(word$)
For i = 2 To Len(word$)-1  
  EXPREG$ + "[A-Z a-z 0-9 _]"
Next 
RE = CreateRegularExpression(#PB_Any,"^[A-Z a-z]"+EXPREG$+"[:]")
If RE
   Result.a = MatchRegularExpression(RE, word$)
   FreeRegularExpression(RE)  
EndIf 
ProcedureReturn Result
EndProcedure

; /////////////////////////////////////////////////////////////////////////////
; Format : B10101010
; /////////////////////////////////////////////////////////////////////////////
Procedure.a isBinary(word$)
For i = 3 To Len(word$)  
  EXPREG$ + "[0-1]"
Next 
RE = CreateRegularExpression(#PB_Any,"^0B"+EXPREG$)
If RE
   Result.a = MatchRegularExpression(RE, word$)
   FreeRegularExpression(RE)  
EndIf 
ProcedureReturn Result
EndProcedure

; /////////////////////////////////////////////////////////////////////////////
; Format : + - * / $
; /////////////////////////////////////////////////////////////////////////////
Procedure.a isOperator(word$)
For i = 1 To Len(word$)  
  EXPREG$ + "[+ \- * / = & <<]"
Next 
RE = CreateRegularExpression(#PB_Any,EXPREG$)
If RE
   Result.a = MatchRegularExpression(RE, word$)
   FreeRegularExpression(RE)  
EndIf 
ProcedureReturn Result
EndProcedure

; /////////////////////////////////////////////////////////////////////////////
;
; /////////////////////////////////////////////////////////////////////////////
Procedure.i ValEX(string.s)
  
  If isHexaDecimal(UCase(string))
    ProcedureReturn Val("$"+StringField(UCase(string),2,"X"))
  EndIf 
  
  If isBinary(UCase(string))
    ProcedureReturn Val("%"+StringField(UCase(string),2,"B"))
  EndIf 
  
  If isDigit(UCase(string))
    ProcedureReturn Val(string)
  EndIf 
  
EndProcedure
tu devrais l'adapté sans problème pour tes besoins.
Mesa
Messages : 1097
Inscription : mer. 14/sept./2011 16:59

Re: isString(), isNumeric()

Message par Mesa »

Comme beaucoup, j'ai voulu faire ma propre macro
For i=0.0 to 1.0 step 0.01
mais comme tout le monde je suis tombé sur l’imprécision des float.

Voici mon essai de macro et c'est lors de test sur "step" qu'il m'aurait fallu une fonction isString() ou isFloat()

Code : Tout sélectionner



Macro ForFs(varf,startf,endf,stepf)
  ;Only float because of the presence of "isNAN()"
  
  ;stepf must be a string : Is it impossible to test it ?
  ; need a macro isString()
  
  
  If stepf ="0" Or stepf=""; step never has to be 0
    Debug "Step musn't be zero"
    ;messagerequester()
    End
  EndIf 
  
  
  ;Because some people can write "For f= 0 to (sqrt(-1)) step 0.2", we have to deal with that
  If IsNAN(startf) Or IsNAN(endf) <> 0
    Debug "Boundaries are not a number"
    ;messagerequester()
    End 
  EndIf
  
  If(startf-endf)*ValF(stepf) > 0 ; check boundary; if startf<endf when stepf>0 => ok etc.
    Debug "Error in Boundaries"
    ;messagerequester()
    
    End
  EndIf
  
  ;Everything is ok now
  varf = startf - ValF(stepf) 
  
  ;Go
  While Bool(varf<=endf And Mid(stepf,1,1)<>"-") Or Bool(varf>=endf And Mid(stepf,1,1)="-")
    varf=varf+ValF(stepf)
    
  EndMacro
  
 Macro ForF(varf,startf,endf,stepf)
  ;Only float because of the presence of "isNAN()"
  
  ;stepf must be a float : Is it impossible to test it ?
  ; need a macro isFloat()
  
  If stepf =0 ; step never has to be 0
    Debug "Step musn't be zero"
    ;messagerequester()
    End
  EndIf 
  
  
  ;Because some people can write "For f= 0 to (sqrt(-1)) step 0.2", we have to deal with that
  If IsNAN(startf)+IsNAN(endf)+IsNAN(endf) <> 0
    Debug "Boundaries are not a number"
    ;messagerequester()
    End 
  EndIf
  
  If(startf-endf)*stepf > 0 ; check boundary; if startf<endf when stepf>0 => ok etc.
    Debug "Error in Boundaries"
    ;messagerequester()
    
    End
  EndIf
  
  ;Everything is ok now
  varf = startf -stepf 
  
  ;Go
  While Bool(varf<endf And stepf>0) Or Bool(varf>endf And stepf<0)
    varf=Round((varf+stepf)*100,#PB_Round_Nearest)/100
    
  EndMacro 
  
  
  
  Macro Nextf()
  Wend
EndMacro

Debug "ForFs step +"
ForFs(f.f, 0.0, 1.0, "0.1")
Debug f
Nextf()

Debug "===================="
Debug "ForFs step -"
ForFs(f.f, 1.0, 0.0, "-0.1")
Debug f
Nextf()

; Debug "===================="
; Debug "ForFs step - error"
; ForFs(f.f, 0.0, 1.0, "-0.1")
; Debug f
; Nextf()
; 
; Debug "===================="
; Debug "ForFs step + error"
; ForFs(f.f, 1.0, 0.0, "0.1")
; Debug f
; Nextf()

Debug "===================="
Debug "===================="
Debug "ForF step +"
ForF(f.f, 0.0, 1.0, 0.1)
Debug f
Nextf()

Debug "===================="
Debug "ForF step -"
ForF(f.f, 1.0, 0.0, -0.1)
Debug f
Nextf()

Debug "===================="
Debug "ForF step - error"
ForF(f.f, 0.0, 1.0, -0.1)
Debug f
Nextf()

; Debug "===================="
; Debug "ForF step + error"
; ForF(f.f, 1.0, 0.0, 0.1)
; Debug f
; Nextf()

Comme la solution doit se trouver dans le calcul à "virgule fixe", existe-t-il une library (même en C) pour ça quelque part ?
Je n'ai rien trouvé de bien.

Sinon, il va falloir passer en assembleur.

Mesa.
Répondre