When playing with some code earlier I noticed a bit of an oddity with some numbers.
function setup()
A = 0
end
function draw()
A = A + 0.0125
B = A // 1
C = math.floor(A)
fill(255); textMode(CORNER)
text(type(A).." = "..A,150,700)
text(type(B).." = "..B,150,680)
text(type(C).." = "..C,150,660)
end
A obviously outputs as a float, whilst B is displayed as “n.0” and C is just displayed as “n”.
I’m not bothered about the output - I know that can be controlled via string.format(), but I was curious as to whether B is actually a true integer.
Turns out in this example you could pass B as a parameter to a function like image.get() (which will fail if you pass A ) or is it due to the fact that B has no fractional part and can therefore be internally converted into an integer.
So it looks like using the new integer divider operator (//) might work as a quick way to floor a value - the question is, is it a faster / cleaner way than using math.floor (or a local reference to math.floor)?
@TheSolderKing Unless you’re writing time sensitive code, I don’t think it really matters which one is used. I’m sure there’s going to be other code in a program that could slow a program down more. Unless you try different statements and time each one, you’ll have slowdowns.
another test (more fair bacause math.floor is copied locally)
-- test speed integer
function setup()
t1 = test1()
t2 = test2()
print("speed increase x"..string.format("%1.1f",t1/t2))
-- typical result speed increase x3.6
end
function test1()
t=os.clock()
local f = math.floor
local a
for z=1,10000000 do
a=f(5.432)
end
t = os.clock()-t
print("local math.floor: ".. tostring(t) )
return t
end
function test2()
t=os.clock()
local f = math.floor
local a
for z=1,10000000 do
a=5.432//1
end
t = os.clock()-t
print("integer division: ".. tostring(t) )
return t
end
@TechDojo the type function will give you the general type of numbers (i.e., it will give you number for all numbers). If you want to see the specific type of number use math.type( n ), which returns float for A and B in your example, but integer for C (because math.floor returns an integer)
I would have thought therefore that math.type(B) would also have been an integer - but I guess the proof of the pudding etc…
Interestingly
B = (A // 1) | 0
print(math.type(B)) -- "Integer"
The reason I was investigating this is because now that bitwise operations are available I wanted to port over some animation code I wrote a while back that allows for things like triggering events on a given frame where individual frames in the animation can have some of the top bit’s set to represent various flags.
I’m wondering also if this will open a whole new “integer only” sub section of Lua where like the emscriptem library for Javascript, if you force values to be integer and then stick to integer math will that give a significant speed increase on calculations?
@TechDojo performance would probably come down to the hardware. On older iOS devices there was a definite performance benefit to integers (and 32 bit floats instead of 64 bit doubles). But with arm64 I probably wouldn’t pursue integers for performance reasons.
Integer division converts operands to integers and does an integer division
It converts the operands to integers, the return type appears to be dependent on the types of the operands:
integer // integer -- return type is integer
integer // float -- return type is float
float // float -- return type is float
This makes sense because if you’re using floats within an integer division you’re likely using the result of that expression with more floating point values, so it avoids the need of a float → integer → float conversion.
@Progrmr235 If you don’t know what it’s for and you don’t know why/how to use it, then you really don’t need it. It’s a way to jump around within a function using “if” statements. If you start using goto’s, it can make your code harder to modify as you add more and more code. If you’ve never used a goto statement, then don’t start now.
@Progrmr235 - the main use of the Goto function is expected to be where you have nested for loops, and you are in the middle somewhere and want to break out of all of them. The break command only breaks out of the loop you are in, so until now, you had to set a variable to true and test for it in each of the nested loops, if you wanted to break out of several loops at once. Now you can just Goto a line that is beyond the end of all the loops.
@yojimbo2000 - i hated compulsory line numbers. I used to leave gaps of 10 to start with, and inevitably, that would not be enough in places. Those were the days when graphics meant using the pset command to colour one pixel at a time!
Yup yup, gaps of 10, I remember that. I think my main use of goto back then was when you realised you needed to insert a bunch of code inbetween, say lines 50 and 60, so you’d have to put 55 GOTO 1000 or whatever.