Make a Number Further From 0

I like Godot, the game engine built by Juan Linietsky & a growing body of contributors. It’s a solid, friendly engine with a solid, amazing community.

I am happy to be part of the community in a very minor capacity. I’m not even developing games lately, but I used to participate in the Facebook page, yet happily I don’t have an account any more. In there someone asked something along of the lines of: How can I make a number above 0, increment, and below decrement. In other words: how to make a number get away from zero always?

He had a code snippet that did the job – while using a few conditionals. I was sleep deprived at the time, gave an embarrassing suggestion, apologized profusely and promptly forgot the matter.

Until I remembered this morning.

So here are two solutions for the problem; one is high-level and can be implemented in GDScript with no trouble; the other is lower level and is – to my intuition – the fastest way short of having a processor instruction to achieve it.

So here goes:

func separate_from_zero(x):
  if x == 0:
    return 0
  return x+abs(x)/x

Which basically divides the absolute value of x by x, resulting in 1 if x>0 and -1 if x<0.

This has the issue of using a division – which takes a lot of cycles. But it avoids the branching situation the fellow presented, with if conditionals here and there. (If number is smaller, subtract one, else add one).

The other solution I thought about exploits the fact that true and false are represented in memory as 1 and 0 respectively, which takes me to this:

int separate_from_zero(int x){
  return x + (x>0) - (x<0);
}

That can be inlined, too, so the overhead of calling the function can be avoided. And you will want to cast to int explicitly, maybe. There are pitfalls on both, and tests should be run to profile, and all that. It’s not even that important of a topic,  really, but I remembered Today and wanted to jot it down for future reference; if this needs to run a few dozen times a second, it may be cool to have it at least be predictable (not branch) within reason.

Leave a Reply

Your email address will not be published. Required fields are marked *