Page 1 of 1
Temporary Double
Posted: Sun Aug 31, 2025 7:11 am
by Piero
I use a "Temporary Double" (IIFn –—> priifn) for all non-string types
Excluding if I exceed type range by some very weird multi-type expression (almost impossible) can it still generate a problem in some case?
Code: Select all
Procedure.d priifn(e,t.d,f.d)
If e : ProcedureReturn t : EndIf : ProcedureReturn f
EndProcedure
Macro IIFn(e,t,f) ; IIFn(true?, trueNumber, falseNumber)
priifn(Bool(e),t,f)
EndMacro
Macro IIF(e,s,delim="|") ; IIF(true?, "trueString|falseString")
StringField(s,Bool(Not(e))+1,delim) ; delimiter can be multi-characters
EndMacro
CompilerIf #PB_Compiler_Debugger
Macro dq : "
EndMacro
Macro diifexpr(e,s,i="is") ; "non-blocking assert" (no CallDebugger)
Debug ~"File: \""+#PB_Compiler_Filename+
~"\"\nLine "+ #PB_Compiler_Line + ~": \""+ dq#e#dq +~"\" "+i+" "+ IIF(e,s)
EndMacro
CompilerElse
Macro diifexpr(e,s,i=""):EndMacro
CompilerEndIf
Debug ~"--- IIF ---\n"
x=10 : Debug "x = "+x
Debug ""+x+" Point"+ IIF(Not(x=1), "s") ; also IIF(x<>1,"s")
Debug ""+x+" is "+ IIF(x&1, "Odd|Even")
diifexpr(1&#False Or x/(x-8)=5, "true|not true!")
Debug ""
x=1 : Debug "x = "+x
Debug ""+x+" Point"+ IIF(x=1, "|s") ; empty StringField
Debug ~"\n--- IIFn ---\n"
Debug IIFn(1=0, 11, 10)
Debug ""+IIFn(1=0, 11, 10)
x = IIFn(1=0, %1011, $F-4-x)
Debug x
Edit: reworded the question while my Idol mk-soft tries (I hope in vain) to debug me

Re: Temporary Double
Posted: Sun Aug 31, 2025 1:43 pm
by mk-soft
Could lead to a conversion error with very large integer values.
integer -> Double -> Double -> Integer
I would always include the return type.
Code: Select all
;-TOP
Procedure.i _IIF_integer(expr, rTrue.i, rFalse.i)
If expr : ProcedureReturn rTrue : Else : ProcedureReturn rFalse : EndIf
EndProcedure
Procedure.l _IIF_long(expr, rTrue.l, rFalse.l)
If expr : ProcedureReturn rTrue : Else : ProcedureReturn rFalse : EndIf
EndProcedure
Procedure.f _IIF_float(expr, rTrue.f, rFalse.f)
If expr : ProcedureReturn rTrue : Else : ProcedureReturn rFalse : EndIf
EndProcedure
Procedure.d _IIF_double(expr, rTrue.d, rFalse.d)
If expr : ProcedureReturn rTrue : Else : ProcedureReturn rFalse : EndIf
EndProcedure
Macro IIF_integer(expr, rTrue, rFalse)
_IIF_integer(Bool(expr), rTrue, rFalse)
EndMacro
Macro IIF_long(expr, rTrue, rFalse)
_IIF_long(Bool(expr), rTrue, rFalse)
EndMacro
Macro IIF_float(expr, rTrue, rFalse)
_IIF_float(Bool(expr), rTrue, rFalse)
EndMacro
Macro IIF_double(expr, rTrue, rFalse)
_IIF_double(Bool(expr), rTrue, rFalse)
EndMacro
Macro IIF_string(expr, rTrue, rFalse)
PeekS(_IIF_integer(Bool(expr), @rTrue, @rFalse))
EndMacro
;-Test
x = 1
a = IIF_integer(x=1, 10, 20)
Debug a
b.f = IIF_float(x=1, 1.0, 2.0)
Debug b
c.s = IIF_string(x=1, "True", "False")
Debug c
Re: Temporary Double
Posted: Sun Aug 31, 2025 1:50 pm
by Piero
mk-soft wrote: Sun Aug 31, 2025 1:43 pm
Could lead to a conversion error with very large integer values.
Can you post an example error? (without exceeding integer range)
I'm very curious!
Thanks!
Edit: I mean, if you start with an integer, how can you get out of range? (hope I was clear)
Edit 2: I was more worried of possible quirks happening when converting .f to .d and back

Re: Temporary Double
Posted: Sun Aug 31, 2025 5:10 pm
by Skipper
Piero,
creating a ternary operator this way will indeed make our sources somewhat more compact, but in the end, the compiler will generate similar binaries - this is especially valid for the optimising C-backend?
Cheers,
Skipper
Re: Temporary Double
Posted: Sun Aug 31, 2025 6:13 pm
by Piero
Skipper wrote: Sun Aug 31, 2025 5:10 pm
Piero,
C-backend?
My C is even more rusty than my JS (what a shame… I had GREAT teachers…) anyway I think that, with a bit of practice, you will easily spot if a macro (expansion) will bloat your source instead of helping you code "better"…
PS about "macros" etc.: I'm tempted to celebrate Fred, but my duty is to criticize… so Form Designer!

Re: Temporary Double
Posted: Sun Aug 31, 2025 6:18 pm
by Skipper
I hope you understood my reference to the PB -C-compiler backend? No need to learn C, really...
Re: Temporary Double
Posted: Sun Aug 31, 2025 8:09 pm
by Piero
Skipper wrote: Sun Aug 31, 2025 6:18 pm
I hope you understood my reference to the PB -C-compiler backend? No need to learn C, really...
Yes I think I understood; It's just I'm not into making ultra-super-fast stuff, and that made me remember of C (you can compile libraries and use with PB…) it also seems to me that with all this "AI" around, compilers are still often dumb (not talking only about PB (gcc?) but again about "optimization for extreme speed")
Edit: here's an example, but I dunno if I misunderstood something (as I said, I'm not into ultrafast coding stuff):
viewtopic.php?p=644508#p644508
Re: Temporary Double
Posted: Mon Sep 01, 2025 8:11 pm
by SMaag
here a collection of different IIF Macros
Code: Select all
; IIF : similar to the VB IIf Function
; use it : IIf(varReturn, A>1000, "large", "small")
Macro IIF(varReturn, _Expression_, valTrue, valFalse)
If Bool(_Expression_)
varReturn = valTrue
Else
varReturn = valFalse
EndIf
EndMacro
;IIFe operating an Expression -> run True/False Expression
; use it: IIFe(a=b, c+d, c*d)
; IIFe(a=b, x=1, x=0)
Macro IIFe(_Expression_, _TrueExpression_, _FalseExpression_)
If _Expression_
_TrueExpression_
Else
_FalseExpression_
EndIf
EndMacro
; IIFn with Numeric retrurn
; use it: numericVar = IIF(a=b, 1, 2)
Macro IIFn(_Expression_, _TruePart_, _FalsePart_)
Bool(_Expression_)*_TruePart_ + Bool(Not(_Expression_))*_FalsePart_
EndMacro
; IIFs with String return from True/False Stringfield
; use it: IIFs(A>1000, "large|small")
Macro IIFs(_Expression_, _TrueStr_FalseStr_, sepStr="|")
StringField(_TrueStr_FalseStr_, 2-Bool(_Expression_), sepStr)
EndMacro
; IIFss with String return from True/False String
; use it: IIFs(A>1000, large, small)
Macro IIFss(_Expression_, _TrueString_, _FalseString_)
PeekS(@_TrueString_,-Bool(_Expression_)) + PeekS(@_FalseString_,-Bool(Not(_Expression_)))
EndMacro
Define res
Debug "IIF returning the True/False Part"
IIF(res, 1=0, 1, 0)
Debug res
IIF(res, 1=1, 1, 0)
Debug res
Debug "IIFe with running the True/False Expression"
IIFe(1=0, res=1, res=0)
Debug res
IIFe(1=1, res=1, res=0)
Debug res
Debug "IIFn with numeric return"
Debug IIFn(1=0, 1, 0)
Debug IIFn(1=1, 1, 0)
Debug "IIFs with retruning True/False Part from a StringField"
Debug IIFs(1=0, "True|False")
Debug IIFs(1=1, "True|False")
Debug "IIFss with True/False String and PeekS()"
Debug IIFss(1=0, "True", "False")
Debug IIFss(1=1, "True", "False")
Re: Temporary Double
Posted: Tue Sep 02, 2025 9:23 am
by Piero
SMaag wrote: Mon Sep 01, 2025 8:11 pm
here a collection of different IIF Macros
I wonder if
Code: Select all
Macro IIF(e,s,delim="|") ; IIF(true?, "trueString|falseString")
StringField(s,~Bool(e)&1+1,delim) ; delimiter can be multi-characters
EndMacro
would be faster
Edit:
Code: Select all
Macro IIFn(_Expression_, _TruePart_, _FalsePart_)
Bool(_Expression_)*_TruePart_ + Bool(Not(_Expression_))*_FalsePart_
EndMacro
Debug IIFn(1=0, 11.1, 10) ; should be 10, gives 0.0!
I prefer my version because it can be used directly with debug and generates/needs less code
Code: Select all
Procedure.d priifn(e,t.d,f.d) ; "temporary Double" for non-String types
If e : ProcedureReturn t : EndIf : ProcedureReturn f
EndProcedure
Procedure.s priifs(e,s.s,d.s)
ProcedureReturn StringField(s,Bool(Not(e))+1,d)
EndProcedure
Macro IIFn(e,t,f) ; IIFn(true?, trueNumber, falseNumber)
priifn(Bool(e),t,f)
EndMacro
#iifsdelim="|"
Macro IIFs(e,s,delim=#iifsdelim) ; IIFs(true?, "trueString|falseString")
priifs(Bool(e),s,delim) ; delimiter can be multi-characters
EndMacro
Macro IIF(e,t,f) ; IIF(a=b?, x=1, s="y")
If Bool(e) : t : Else : f : EndIf ; Bool just in case
EndMacro
CompilerIf #PB_Compiler_Debugger
Macro dq : "
EndMacro
Macro diifexpr(e,s,i="is") ; "non-blocking assert" (no CallDebugger)
Debug ~"File: \""+#PB_Compiler_Filename+
~"\"\nLine "+ #PB_Compiler_Line + ~": \""+ dq#e#dq +~"\" "+i+" "+ IIFs(e,s)
EndMacro
Macro BadAssert(e,t="") ; blocking if true
If e
Debug ~"File: \""+#PB_Compiler_Filename+
~"\"\nLine "+ #PB_Compiler_Line + ~": \""+ dq#e#dq +~"\" is true! "+t
CallDebugger
EndIf
EndMacro
CompilerElse
Macro diifexpr(e,s,i=""):EndMacro
Macro BadAssert(e,t=""):EndMacro
CompilerEndIf
BadAssert(x<>0,x) ; x should be 0 (and is also integer) by default
Debug ~"--- IIFs ---\n"
x=10 : Debug "x = "+x
Debug ""+x+" Point"+ IIFs(Not(x=1), "s") ; also IIFs(x<>1,"s")
Debug ""+x+" is "+ IIFs(x&1, "Odd|Even")
diifexpr(1&#False Or x/(x-8)=5, "true|not true!")
Debug ""
x=1 : Debug "x = "+x
Debug ""+x+" Point"+ IIFs(x=1, "|s") ; empty StringField
Debug ~"\n--- IIFn ---\n"
Debug IIFn(1=0, 11, 10) ; it's Double, but…
Debug ""+IIFn(1=0, 11, 10) ; becomes Integer on a "string"
x = IIFn(1=0, %1011, $F-4-x) ; becomes type of x (Integer in this case)
Debug x
Edit: added #iifsdelim and made IIFs use a procedure; should generate less code (but lose some nanosecond

)
Suggestions welcome!
Re: Temporary Double
Posted: Tue Sep 02, 2025 5:12 pm
by SMaag
Macro IIFn(_Expression_, _TruePart_, _FalsePart_)
Bool(_Expression_)*_TruePart_ + Bool(Not(_Expression_))*_FalsePart_
EndMacro
Debug IIFn(1=0, 11.1, 10) ; should be 10, gives 0.0!
seems to be a PB-Bug!
If I change the to statements it works
Code: Select all
EnableExplicit
Macro IIFn(_Expression_, _TruePart_, _FalsePart_)
; Bool(Not _Expression_) * _FalsePart_ + Bool(_Expression_) * _TruePart_
Bool(_Expression_) * _TruePart_ + Bool(Not _Expression_) * _FalsePart_
EndMacro
Debug IIFn(1=0, 11.1, 10) ; should be 10, gives 0.0!
Define res.d
res = IIFn(1=0, 11.1, 10) ; should be 10, gives 0.0!
Debug res
Re: Temporary Double
Posted: Tue Sep 02, 2025 6:21 pm
by Piero
SMaag wrote: Tue Sep 02, 2025 5:12 pmseems to be a PB-Bug!
If I change the to statements it works
(In case, please forgive my dumbness

) What "to statements"? Here your examples always give 0.0

Re: Temporary Double
Posted: Tue Sep 02, 2025 7:16 pm
by SMaag
(In case, please forgive my dumbness

) What "to statements"? Here your examples always give 0.0

Top
Code: Select all
; this 2 lines in the Macro return different values - but should be the same
Macro IIFn(_Expression_, _TruePart_, _FalsePart_)
Bool(Not _Expression_) * _FalsePart_ + Bool(_Expression_) * _TruePart_
;Bool(_Expression_) * _TruePart_ + Bool(Not _Expression_) * _FalsePart_
EndMacro
it is a bug of the compilers precalculation!
viewtopic.php?t=87478
Re: Temporary Double
Posted: Tue Sep 02, 2025 7:41 pm
by Piero
SMaag wrote: Tue Sep 02, 2025 7:16 pmthis 2 lines in the Macro return different values - but should be the same
Code: Select all
Macro IIFn(_Expression_, _TruePart_, _FalsePart_)
Debug Bool(Not _Expression_) * _FalsePart_ + Bool(_Expression_) * _TruePart_
Debug Bool(_Expression_) * _TruePart_ + Bool(Not _Expression_) * _FalsePart_
EndMacro
IIFn(1=1, 11.1,10)
; 11.0999999999999996
; 21.1000000000000014
viewtopic.php?t=87478
Fred! Help!
