Temporary Double

Just starting out? Need help? Post your questions and find answers here.
User avatar
Piero
Addict
Addict
Posts: 913
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Temporary Double

Post 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 :)
Last edited by Piero on Sun Aug 31, 2025 3:38 pm, edited 2 times in total.
User avatar
mk-soft
Always Here
Always Here
Posts: 6242
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Temporary Double

Post 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
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Piero
Addict
Addict
Posts: 913
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Temporary Double

Post 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 :?
User avatar
Skipper
User
User
Posts: 54
Joined: Thu Dec 19, 2024 1:26 pm
Location: NW-Europe

Re: Temporary Double

Post 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
<< Win-11 (x64) / Mint linux (x64) / MacOS Monterey (x64) >>
User avatar
Piero
Addict
Addict
Posts: 913
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Temporary Double

Post 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! :evil:
User avatar
Skipper
User
User
Posts: 54
Joined: Thu Dec 19, 2024 1:26 pm
Location: NW-Europe

Re: Temporary Double

Post by Skipper »

I hope you understood my reference to the PB -C-compiler backend? No need to learn C, really...
<< Win-11 (x64) / Mint linux (x64) / MacOS Monterey (x64) >>
User avatar
Piero
Addict
Addict
Posts: 913
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Temporary Double

Post 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
SMaag
Enthusiast
Enthusiast
Posts: 324
Joined: Sat Jan 14, 2023 6:55 pm
Location: Bavaria/Germany

Re: Temporary Double

Post 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")
User avatar
Piero
Addict
Addict
Posts: 913
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Temporary Double

Post 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!
SMaag
Enthusiast
Enthusiast
Posts: 324
Joined: Sat Jan 14, 2023 6:55 pm
Location: Bavaria/Germany

Re: Temporary Double

Post 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
User avatar
Piero
Addict
Addict
Posts: 913
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Temporary Double

Post 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 :D) What "to statements"? Here your examples always give 0.0 :(
SMaag
Enthusiast
Enthusiast
Posts: 324
Joined: Sat Jan 14, 2023 6:55 pm
Location: Bavaria/Germany

Re: Temporary Double

Post by SMaag »

(In case, please forgive my dumbness :D) 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
User avatar
Piero
Addict
Addict
Posts: 913
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Temporary Double

Post 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! :mrgreen:
Post Reply