Page 3 of 3
Re: IIF functionality made simple
Posted: Tue Nov 10, 2009 2:36 am
by mesozorn
Kaeru Gaman wrote:why 1- and Not, when you have the And..?
Because try this...
...and you'll see why I don't use it by itself. It works for variables but I prefer a version that works for everything imaginable, including literals. This way:
Code: Select all
z=(1-(1 And Not(5.5>5.6)))
Debug z
z=(1-(1 And Not(5.5>5.3)))
Debug z
...works for both/all contingencies.
Re: IIF functionality made simple
Posted: Tue Nov 10, 2009 2:59 am
by mesozorn
idle wrote:or this and is probably quicker than a not
Code: Select all
Macro IIFn(expr,y,n)
IIFEvaln((1 And(expr)),y,n)
EndMacro
Macro IIF(expr,y,n)
IIFEval((1 And(expr)),y,n)
EndMacro
LOL... that was my original, original version months ago, and its failure to properly handle literal floats like (5.5>5.3) as expressions is what led me down the whole Val(Str()) path in the first place. It's true that the above will work for the majority of situations, but not all of them, unlike the two versions we arrived at earlier today.
Re: IIF functionality made simple
Posted: Tue Nov 10, 2009 5:36 am
by idle
it works for floats but it won't return them
Re: IIF functionality made simple
Posted: Tue Nov 10, 2009 6:53 am
by mesozorn
idle wrote:it works for floats but it won't return them
Er.. what do you mean exactly?
Re: IIF functionality made simple
Posted: Tue Nov 10, 2009 8:01 am
by idle
improved the string speed but you need to pass the address of the string
just call the macro with the return types you want
edit bloddy dyslexia!
edit to NOT as (1 And 5.5 = 5.6) dosen't work
iFFI , iFFF, IFFD, IFFQ, IFFS
Code: Select all
Procedure.s IIFEvals(expr,*y,*n)
If expr
ProcedureReturn PeekS(*y)
Else
ProcedureReturn PeekS(*n)
EndIf
EndProcedure
Procedure IIFEvali(expr,y,n)
If expr
ProcedureReturn y
Else
ProcedureReturn n
EndIf
EndProcedure
Procedure.f IIFEvalf(expr,y.f,n.f)
If expr
ProcedureReturn y
Else
ProcedureReturn n
EndIf
EndProcedure
Procedure.d IIFEvald(expr,y.d,n.d)
If expr
ProcedureReturn y
Else
ProcedureReturn n
EndIf
EndProcedure
Procedure IIFEvalq(expr,y.q,n.q)
If expr
ProcedureReturn y
Else
ProcedureReturn n
EndIf
EndProcedure
Macro IFFI(expr,y,n)
IIFEvali((Not(expr)),n,y)
EndMacro
Macro IFFF(expr,y,n)
IIFEvalf((Not(expr)),n,y)
EndMacro
Macro IFFD(expr,y,n)
IIFEvald((Not(expr)),n,y)
EndMacro
Macro IFFQ(expr,y,n)
IIFEvalf((Not(expr)),n,y)
EndMacro
Macro IFFS(expr,y,n)
IIFEvals((Not(expr)),n,y)
EndMacro
Macro IFFfn(expr,a,b)
If expr : a : Else : b : EndIf
EndMacro
Procedure p2(a.s)
MessageRequester("test",a)
EndProcedure
a=5
b=4
c=2
d=3
e.f = 5.6
f.f = 5.5
IFFfn(5>4,p2("hello"),MessageRequester("test","no"))
Debug IFFS(5.5>5.4,@"yes",@"no")
Debug IFFI(a > b,200,100)
Debug IFFF(e > f,200.1234567,100.1234567)
Debug IFFD(5.5 = 5.6,200.123456789012345,10.123456789012345)
Debug IFFQ(a > c,$FFFFFFFF,$EEEEEEEE)
lp = 1000000
st = GetTickCount_()
For a = 1 To lp
x$ = iFFs(5.5 > 7.5,@"200",@"100")
Next
et1.f = (GetTickCount_() - st) / lp
st = GetTickCount_()
For a = 1 To lp
If 5.5 > 7.5
x$ = "200"
Else
x$ = "100"
EndIf
Next
et2.f = (GetTickCount_() - st) / lp
MessageRequester("test", "IFFs " + StrF(et1,6) + " if " + StrF(et2,6))
Re: IIF functionality made simple
Posted: Tue Nov 10, 2009 8:10 am
by mesozorn
idle wrote:improved the string speed but you need to pass the address of the string
just call the macro with the return types you want
It still doesn't handle literal floats correctly though with only (1 and expr). Uncomment and change your line to:
Code: Select all
Debug IIFD(5.5=5.6,200.123456789012345,10.123456789012345)
Debug IIFS(5.5>5.7,@"yes",@"no")
...and note that it still returns the "yes" result both times, even though 5.5 doesn't equal 5.6 in the first example, and 5.5 isn't greater than 5.7 in the second.
Re: IIF functionality made simple
Posted: Tue Nov 10, 2009 8:19 am
by idle
ohh crap! yes you are right
changed it back to not
Re: IIF functionality made simple
Posted: Tue Nov 10, 2009 8:26 am
by mesozorn
idle wrote:ohh crap! yes you are right

Hehe... for those ones it seems we still can't get away from using one of the two methods discovered earlier to handle them accurately. Either just the Not by itself or the "barbarous abomination" (1-(1 And Not(expr))).
I still don't know why only the barbarous one returns correctly in all cases (straight variable value assign debug) while the Not one by itself only works in the procedure but not independently. Odd quirk.
Re: IIF functionality made simple
Posted: Wed Nov 11, 2009 4:10 am
by idle
I don't know anymore I'm so confused.

It appears to be around a 2x speed penalty in all cases so it's a pretty good improvement.
Code: Select all
Procedure.s IIFEvals(expr,*y,*n)
If expr
ProcedureReturn PeekS(*y)
Else
ProcedureReturn PeekS(*n)
EndIf
EndProcedure
Procedure.i IIFEvali(expr,y,n)
If expr
ProcedureReturn y
Else
ProcedureReturn n
EndIf
EndProcedure
Procedure.f IIFEvalf(expr,y.f,n.f)
If expr
ProcedureReturn y
Else
ProcedureReturn n
EndIf
EndProcedure
Procedure.d IIFEvald(expr,y.d,n.d)
If expr
ProcedureReturn y
Else
ProcedureReturn n
EndIf
EndProcedure
Procedure.q IIFEvalq(expr,y.q,n.q)
If expr
ProcedureReturn y
Else
ProcedureReturn n
EndIf
EndProcedure
Macro IIFI(expr,y,n)
IIFEvali((Not(expr)),n,y)
EndMacro
Macro IIFF(expr,y,n)
IIFEvalf((Not(expr)),n,y)
EndMacro
Macro IIFD(expr,y,n)
IIFEvald((Not(expr)),n,y)
EndMacro
Macro IIFQ(expr,y,n)
IIFEvalf((Not(expr)),n,y)
EndMacro
Macro IIFS(expr,y,n)
IIFEvals((Not(expr)),n,y)
EndMacro
Macro IIFfn(expr,a,b)
If expr : a : Else : b : EndIf
EndMacro
;================================
Procedure p1(a.s)
MessageRequester("P1",a)
EndProcedure
Procedure p2(a.s)
result = MessageRequester("P2",a,#PB_MessageRequester_YesNo)
If result = #PB_MessageRequester_Yes
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
a=5
b=4
c=2
d=3
e.f = 5.6
f.f = 5.5
Debug IIFS(5.4 = 5.4,@"yes",@"no") ;string return
Debug IIFI(a > b,200,100) ;Integer return
Debug IIFF(e > f,200.1234567,100.1234567) ;float return
Debug IIFD(5.5 = 5.6,200.123456789012345,10.123456789012345) ;Double return
Debug IIFQ(a > c,$FFFFFFFFF,$EEEEEEEE) ;quad return
;function call a regular macro with no return
IIFfn(a>b And c>d,p1("true"),p1("false"))
; iif as a parameter in a function expecting a string calling a function with the result from the input
p1(iifs(p2("Click Yes or Cancel"),@"You Clicked Ok",@"You Clicked Cancel"))
;iif getting the result of a function
If CreateFile(0, "MacroTest.txt")
CloseFile(0)
Debug "Delete File : " + IIFs(DeleteFile("MacroTest.txt"),@"Yes",@"No")
EndIf
Re: IIF functionality made simple
Posted: Mon Apr 26, 2010 7:05 am
by avatar
This is my version of string handling in IIF
Code: Select all
Procedure.s IIFEvalss(expr,y.s,n.s)
If expr
ProcedureReturn y
Else
ProcedureReturn n
EndIf
EndProcedure
Macro IIFSS(expr,y,n)
IIFEvalss((Not(expr)),n,y)
EndMacro
Debug iifss(1=0,"TRUE","FALSE")
Debug iifss(1=1,"TRUE","FALSE")