I've seen both sgn(0)==1 and sgn(0)==0 in various code bases, and also less ambiguous versions: sgn0(), sgn2(), sgn3() that return 3, 2 and 3 possible values respectively. After a quick survey, it looks like sgn(0)==0 is more typical and maybe has some mathematical basis (?). It's still not too late to change the behaviour in pico-8 I think.
Just out of curiosity, anyone care to give an example of when sgn(0)==0 is more useful? I generally use it in situations where only a non-zero result is meaningful. e.g. player.x + sgn(player.dx) * player.w to get the point in front of a player.
A common example of sgn(0)==0 would be in collision. The standard grid raycast loop uses it, since you don't want to step if you're moving zero in x or y:
sx = sgn(dx) sy = sgn(dy) gx = flr(x/scale) gy = flr(y/scale) curt = 0 dxt = sx*scale/dx dyt = sy*scale/dy #full grid step in t, div by 0=max in lua? nxt = sx == 0 and 2 or ((scale*gx+.5*scale*(sx+1)) - x) / dx #first x in t nyt = sy == 0 and 2 or ((scale*gy+.5*scale*(sy+1)) - y) / dy #first y in t while(curt < 1) do if(nxt < nyt) then curt=nxt gx+=sx nxt+=dxt else curt=nyt gy+=sy nyt+=dyt end #do something at grid position (gx,gy) end
I can't really think of other places where sign(x) is used offhand, it's kind of a rare function. Also that code is from memory, so don't trust me on it. =)
Hey! I poked you Zep on twitter about this without realizing it was already being discussed.
sgn(0) = 0 is definitely the more common one in my experience; Flashpunk uses it in its utility functions, as does the C# standard Math library. Since zero is signless (usually), it doesn't seem correct to me for it to return 1.
I was planning to use this recently for an input system, making use of the new input bitfield like so:
local keys = btn() x += sgn(band(keys, 2)) - sgn(band(keys, 1)) y += sgn(band(keys, 8)) - sgn(band(keys, 4))
Versus how I usually do it:
if btn(0) then x -= 1 end if btn(1) then x += 1 end if btn(2) then y -= 1 end if btn(3) then y += 1 end
I've just now tested it and apparently I'm not actually saving on tokens, haha. Maybe I don't want this feature after all ;)
In terms of saving tokens or writing elegant code, I think sgn(0)==0 vs. sgn(0) == 1 is much of a muchness. More important is that it behaves as you'd expect it to without reading the manual (when there is an entry!), and it seems most users expect sgn(0) == 0. I'll see about changing it to return 0 in 0.1.5 if there's a way to do it without breaking carts in the wild too much.
[Please log in to post a comment]