Archive 17/01/2023.

Sin of 360 degree return bad value

AntiLoxy

Please someone can tell me why std::sin(M_PI * 2); or Urho3D::Sin(360.0f) return a bad value.
I expect return equal to 0.

Sample of a returned values: 1.74845553e-07.

Sinoid

It’s the table maker’s dilemma. The transcendental functions are well known to be unreliable if you’re after accuracy (they have consistency and precision though).

It’s super fun when you’re dealing Q-numbers.

Modanung

I use quadratic approximation. Maybe it behaves more how you would expect your sine functions to work.

Code
float LucKey::Sine(float x)
{
    x = Cycle(x, -M_PI, M_PI);

    float sin{};

    if (x < 0.0f)
        sin = 1.27323954f * x + 0.405284735f * x * x;
    else
        sin = 1.27323954f * x - 0.405284735f * x * x;

    if (sin < 0)
        sin = 0.225f * (sin *-sin - sin) + sin;
    else
        sin = 0.225f * (sin * sin - sin) + sin;

    return sin;
}
float LucKey::Cosine(float x)
{
    return Sine(x + M_PI * 0.5f);
}
float LucKey::Cycle(float x, float min, float max)
{
    float res{ x };
    if (min > max) {

        float temp{ min };
        min = max;
        max = temp;
    }

    float range{max - min};

    if (x < min)
        res += range * abs(ceil((min - x) / range));
    else if (x > max)
        res -= range * abs(ceil((x - max) / range));

    return res;
}
johnnycable

That is Zero!
[20 char filler]

Modanung

Actually it’s 0,000000174845553… which is pretty close. :slightly_smiling_face:

AntiLoxy

Ok, so it’s normal that is not a perfect 0, thanks for all !

codexhound

That’s not incorrect. Those functions are approximations as you can only go so far. 1.749*10e-07 is essentially zero. Just insert a tolerance that turns anything close to 0 into 0.

Valdar

And to clarify, it’s basically a roundoff error and not specific to Urho.
The result of some calculations (especially trigonometry) would require infinite space to hold in floating-point notation. Due to the finite length of memory locations, those results get truncated and you lose a slight amount of accuracy. In most cases, you won’t notice, but in calculations that repeat many times, you should be aware. The error will accumulate each time and potentially become an issue. In those cases, you may want to manually mitigate the error as @codexhound mentioned.

johnnycable

Yes. There’s no such thing as a discrete zero value in computer calculations, unless you use something like http://www.mpir.org/

more madness here: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

Modanung

Interesting links

Don’t store that float

“Elapsed game time should never be stored in a float. Use a double instead.”

Urho uses floats because of backwards compatibility, right? Since - as I understand it - it makes no difference, performance-wise, on modern (64-bit?) architecture.