what does this mean ? (blitz3d code)

Community Forums/General Help/what does this mean ? (blitz3d code)

RemiD(Posted 2016) [#1]
Hello,

Today i was searching for some formulas in the forums/codesarchives and i found this in a code
range1% = Ua >= 0.0 And Ua <= 1.0
range2% = Ub >= 0.0 And Ub <= 1.0

wtf ?

i was not aware that it was allowed to write such thing...

Can somebody please translate each line in words so that i can understand what is going on.

Thanks,


Floyd(Posted 2016) [#2]
An expression such as Ua >= 0.0 evaluates to True or False, which really means 1 or 0.

Thus range1% is an integer which takes the value 1 if Ua is in the range 0.0 to 1.0 and is 0 otherwise.


TomToad(Posted 2016) [#3]
Basically If Ua>= 0.0 And Ua <= 1.0 Then range1% = 1 Else range1% = 0
Can be quite handy at times.
you can change
If A = 1 Then
    B = 1
Else If A = 2
    B = 2
Else If A = 3
    B = 4
End If

into
B = (A = 1) + 2*(A = 2) + 4*(A = 3)



Derron(Posted 2016) [#4]
@ TomToad

In your special example it might be better to have "Select" - or even just a "B = 2^(A-1)" as it saves multilpe comparisons (ignoring the expense of the power^operator here and assuming it should be done until A=20 ;-))


In general I find it sad that it isn't possible to do similar things with strings:

print "I am a " + (gender=1)*"girl" + (gender=2)*"boy"

Also it is similar to ternary operators:
print "I am a " + (gender=1 ? "girl" : "boy")

which is sadly also not possible but very often would come handy.


bye
Ron


TomToad(Posted 2016) [#5]
True, but here is an example where it actually helps. a rotating counter from 0 to 4, faster than using Mod or If/Then



Derron(Posted 2016) [#6]
Double post because of edit-forum-bug.


Derron(Posted 2016) [#7]
Indeed a nifty "hack" ... but for me the second one is the fastest


SuperStrict
Framework Brl.StandardIO

local time:int = MilliSecs()
local a:int = 0

For local i:int = 1 To 100000000
	a = (a + 1)*(a = 4)
Next
Print MilliSecs() - time

time = MilliSecs()
a = 0
For local i:int = 1 To 100000000
	a = a + 1
	If a > 4 Then a = 0
Next
Print MilliSecs() - time

time = MilliSecs()
a = 0
For local i:int = 1 To 100000000
	a = (a + 1) Mod 5
Next
Print MilliSecs() - time


output:
./bmk makeapp -t console -quick -r -x "optimization_mod4.bmx"
[ 77%] Processing:optimization_mod4.bmx
[ 88%] Compiling:optimization_mod4.bmx.console.release.linux.x86.s
flat assembler  version 1.68  (32768 kilobytes memory)
3 passes, 969 bytes.
[100%] Linking:optimization_mod4
Executing:optimization_mod4
248
124
975



And I wonder why this isnt much faster:
For local i:int = 1 To 100000000
	if a > 4
		a = 0
	else
		a :+ 1
	endif
Next

As it should save an assignment every "5 ticks" (only adds if not resetting).


PS: More important is, your code resets to "a = 0" on every run.
Should be:
a = (a + 1)*(a <> 4)
instead of
a = (a + 1)*(a = 4)


PPS: Compiling with NG seems to benefit from GCC optimizations. Time is "0 ms" (adding in "Rand(0,100)" in each cycle adds some time - so it really optimizes things out there)

bye
Ron


Brucey(Posted 2016) [#8]
Compiling with NG ... Time is "0 ms"

Possibly because you are not reading "a" after the loop?


Derron(Posted 2016) [#9]
I did a "print a" afterwards (which was 0).

I also tested if it really does something (reducing to "0 to 10" and printing out the intermediate "a"s).

edit: did that again and now it correctly "has time"





Executing:untitled2
212 for "a = (a + 1)*(a <> 4)"   sum=200000000
138 for "If a > 4 Then a = 0"   sum=200000000
157 for "If a >= 4 Then ..Else"   sum=200000000
415 for "a = (a + 1) Mod 5"   sum=200000000



bye
Ron


Derron(Posted 2016) [#10]
Double post because of edit-post-forum-bug.


RemiD(Posted 2016) [#11]

An expression such as Ua >= 0.0 evaluates to True or False, which really means 1 or 0.


oh i see...

So in this case range1% will be 1 (or true) if both tests are true, correct ?
and same thing for range2%, it will be 1 (or true), if both tests are true, correct ?



Basically If Ua>= 0.0 And Ua <= 1.0 Then range1% = 1 Else range1% = 0


oh ok, i think i understand.


Thanks !


col(Posted 2016) [#12]
Thats interesting...

I get

227 for "a = (a + 1)*(a <> 4)"   sum=200000000
65 for "If a > 4 Then a = 0"   sum=200000000
65 for "If a >= 4 Then ..Else"   sum=200000000
321 for "a = (a + 1) Mod 5"   sum=200000000

in NG x64.

I'm pretty sure that GCCollect() won't make any difference between the loops, however using it just before starting the first loop would clean up anything that needs to be done beforehand so that no collection can take place while testing.


Derron(Posted 2016) [#13]
Does that "#2 and #3 are nearly the same" mean, that "if ... then" could be nearly neglected (are nearly without "cost") ?

I always assumed

doSomethingA
if bla then DoSomethingB

is more costly than

if not bla then DoSomethingB else DoSomethingA

because "else" is ignored as long as "not bla" is true. So in our case it should be the case for every 5th iteration of the loop - means 20% of the whole procedure. The "if bla" should be true for 80% of the iterations. (if something is <50%, you should check this before conditions with higher probabilities in conditions).


@ GCCollect()
Was just a simple try to make the loops start "fresh" each time - because reordering the 4 variations results in other measurement times (#2 and #3 might change places)

Maybe it would be better to just disable GC for the measurements.



bye
Ron