- Home /
Why does Mathf.Sign(0.0f) return 1?
According to this wikipedia article it should return 0 if x == 0. Unity3D however returns 1 if x == 0.
Now I'm not sure if I'm blaming Unity3D correctly, maybe I misinterpreted the article. But is there a Math function which does work like Mathf.Sign() only returns 0 when x == 0?
For example I want this:
Mathf.Sign(0.1f) == 1;
Mathf.Sign(10.6f) == 1;
Mathf.Sign(-0.2f) == -1;
Mathf.Sign(0.0f) == 0;
Answer by whydoidoit · Jul 11, 2012 at 01:29 PM
Because 0 is considered a positive number by Unity it returns 1 you will have to test for 0 explicitly or write your own function.
static function Sign(number : float) {
return number < 0 ? -1 : (number > 0 ? 1 : 0);
}
Thanks for your reply. I already did that, but I was hoping I overlooked a math function. Seeing other people will look at my code I don't want to look like an idiot and rewrite existing functions ;)
Why is there a discrepancy between Unity's Sign() and the one on wiki?
There is not a hard and fast rule about the Sign of (0) - it is easily explainable that 0 is a positive number - I wouldn't rely on Wikipedia to reference how functions should work :)
I know i am necro-posting, but I wanted to point out that "zero" represents "nothing", the absence of something. It's easy to view it as non-positive, just as much as one can view it as non-negative.
But back to coding, with int a 0 is false and 1 is true, therefore it seems quite intuitive that 0f would also be false.
Wtf?! Signum is mathematical function that is pretty much same in any math book. Does unity interpret other $$anonymous$$athf functions in its own way too? I am starting to fear to use their sinus...
Yes, the signum function is a mathematical function. However we talk about program$$anonymous$$g here. $$anonymous$$any things work different here. We have a signed zero, we have +/- infinity as an actual value, Dividing by 0 is possible (except 0/0),...
In many program$$anonymous$$g languages the sign function will return -1 only for negative numbers. It's often implemented as just reading the sign bit of the number or like this val<0?-1:1
;
Note that "most" of the methods in $$anonymous$$athf directly map to the System.$$anonymous$$ath functions. However Sign is an excpetion (System.$$anonymous$$ath.Sign and UnityEngine.$$anonymous$$athf.Sign). In many cases, especially when dealing with floating point numbers, you rarely actually have the value zero. For example Sign might be used to deter$$anonymous$$e the movement direction or might be used in some related calculation. A value of 0 could cause issues.
Note there's no right or wrong way. This is not about pure mathematics but about what's practical and useful. A signed zero does not exist in actual mathematics. However the IEEE 745 standard provides many useful usecases for a signed zero and infinity.
O$$anonymous$$ assu$$anonymous$$g there is no $$anonymous$$athf function that does it for me I choose it as the accepted answer. Thanks again!
You can use System.$$anonymous$$ath.Sign, which returns 0 if the input is 0; no need to write your own function.
Answer by Regent2203 · Dec 15, 2017 at 02:21 PM
You should use Math.Sign() instead of Mathf.Sign().
Mathf is Unity's library, returns only -1 and 1... just as written in documentation: https://docs.unity3d.com/ScriptReference/Mathf.Sign.html
Math is c# 's library, and works "correctly" (same as mathematical signum function), returns -1,0,1.
the na$$anonymous$$g of Unity's library does give it some sense/validation: $$anonymous$$athf indicates that it's for floats and floats have both a positive and a (rarely used) negative zero.
While it is true that the floating point format has a signed zero, it's irrelevant here as both zeros are considered equal.
float pz = 0f;
float nz = -0f;
if (pz > nz) // false
if (pz < nz) // false
if (pz == nz) // true
// bitwise they are not equal
var l1 = System.BitConverter.DoubleToInt64Bits( nz );
var l2 = System.BitConverter.DoubleToInt64Bits( pz );
if (l1 == l2) // false
The sign of a zero is only relevant in calculations. So -0
is also considered "positive" by Unity. The reason why Unity may did that is probably more practical. If you use the sign as a multiplicator it never turns "0" which could give you several issues when you need a normalized vector for example