Equivalent to Gamemaker's sign() function?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

Equivalent to Gamemaker's sign() function?

Post by hasen »

There is a function in gamemaker studio that is quite useful but it doesn't seem to be the same as Math.sin evidently. It works like this:

"This function returns whether a number is positive, negative or neither and returns 1, -1, 0 respectively. For example - sign(458) will return 1, sign(-5) will return -1 and sign(0) will return 0."

Is there any way to do this with Lua?
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Equivalent to Gamemaker's sign() function?

Post by grump »

Code: Select all

function sign(n)
	return n < 0 and -1 or n > 0 and 1 or 0
end
hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

Re: Equivalent to Gamemaker's sign() function?

Post by hasen »

Ok thanks. Just wondered if there was a set Math function in lua for that.
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Equivalent to Gamemaker's sign() function?

Post by zorg »

There isn't; quite a few small math functions are missing from lua's math library.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Equivalent to Gamemaker's sign() function?

Post by raidho36 »

Worth noting that all languages that have it, implement sign funciton that way - there is no hardware CPU operation to which such function would map, so it has to be done in software anyway.

If your target CPU supports hardware min and max functions, and assuming that LuaJIT can leverage them, you can use the following branchless function:

Code: Select all

function sign ( val ) return math.max ( math.min ( val * math.huge, 1 ), -1 ) end
I don't know if it's any good performance-wise, though you cache the math library data to upvalues and that'll improve something. In interpreted mode it probably wouldn't improve anything - the whole reason interpretation is slow is because there's a failed prediction of an execution branch at every single step of the way.
User avatar
pgimeno
Party member
Posts: 3549
Joined: Sun Oct 18, 2015 2:58 pm

Re: Equivalent to Gamemaker's sign() function?

Post by pgimeno »

Since we're nitpicking I'll play too ;)

I prefer this slight variant of grump's code:

Code: Select all

function sign(n)
	return n < 0 and -1 or n > 0 and 1 or n
end
It returns -1 for a negative number, 1 for a positive number, 0 for positive zero, -0 for negative zero, Not a Number for a NaN input and indeterminate for an indet input. I certainly prefer it to propagate NaNs/indets.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Equivalent to Gamemaker's sign() function?

Post by ivan »

I like grump's version best but I have to throw this one in:

Code: Select all

function sign(n)
  return n == 0 and 0 or n/math.abs(n)
end
Could be simplified if you are certain that n is non-zero:

Code: Select all

assert(n ~= 0)
sign = n/math.abs(n)
coffeecat
Prole
Posts: 29
Joined: Sun Sep 13, 2015 4:10 pm

Re: Equivalent to Gamemaker's sign() function?

Post by coffeecat »

Both * and / are quite costly for floating numbers, if LuaJIT can't help to optimize. A simple branching like grump's version could be more efficient.

The most efficient way to do this is probably by bitwise operations on the binary representation of floating number, if there's no CPU instruction for this. I don't know how this can be done in Lua though.
Rubbermaid
Prole
Posts: 6
Joined: Fri Jan 05, 2018 10:56 pm

Re: Equivalent to Gamemaker's sign() function?

Post by Rubbermaid »

coffeecat wrote: Sat Feb 10, 2018 2:09 pm Both * and / are quite costly for floating numbers, if LuaJIT can't help to optimize. A simple branching like grump's version could be more efficient.

The most efficient way to do this is probably by bitwise operations on the binary representation of floating number, if there's no CPU instruction for this. I don't know how this can be done in Lua though.
I have no idea if this is how bitwise operations work in Lua, but given that all of the numbers are 64-bit doubles I imagine it would look something like:

Code: Select all

sign(n) = ((n & 0x8000000000000000 ~= 0) and -1) or 1
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Equivalent to Gamemaker's sign() function?

Post by zorg »

Rubbermaid wrote: Sat Feb 10, 2018 3:06 pm I have no idea if this is how bitwise operations work in Lua, but given that all of the numbers are 64-bit doubles I imagine it would look something like:

Code: Select all

sign(n) = ((n & 0x8000000000000000 ~= 0) and -1) or 1
There are no bitwise operations in lua (at least not in the version löve uses by default)... not using symbols that is, and luaJIT's bitop module functions return signed 32bit numbers; maybe something like the following may work, although ultimately i haven't tested it, and it doesn't have a separate retval for 0.

Code: Select all

function sign(n) return bit.rshift(bit.band(n, bit.tobit(0x80000000)), 31) == 1 and -1 or 1 end
Then again, it is a bit silly to want to do such """""""""""optimalization""""""""""" on such a function. :|
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Post Reply

Who is online

Users browsing this forum: No registered users and 84 guests