lundi 11 novembre 2019

Best way calculating remainder on floating points

Question

What is the computational cost of the remainder function, is there a specific instruction to calculate it in a cheap way in a specific case?

Description

I need to transform a mathematical variable x into the range of I=[-0.5; 0.5) from R=[-2; 2). While x is not element of I, then x is shifted towards I by repeatedly adding or subtracting 1 to the value of x. x is represented with double x in my code. I need the fastest way of this transformation for this I and R values but wider R ranges can be also interesting.

Ideas and speed comparison

The function I was suggested to use was the naive implementation following the description:

void shift_to_I(double& x) // version 1
{
    while (x < -0.5)
            x += 1;

    while (x >= 0.5)
            x -= 1;
}

Not only for speed considerations but also for code quality I was thinking of using remainder from <cmath> introduced in c++11. With remainder the code shortens to

void shift_to_I(double& x) // version 2
{
    x = remainder(x,1);
}

I had to realize though that it was slower than the original function on my architecture (Intel i7 whatver with VC++). I believed there was a dedicated instruction for this purpose, but either the compiler doesn't know it or it doesn't exist. For wider R interval (on my architecture it is around [-25; 25)) the second version will be faster but I need a code that is fast for narrow intervals too. clang and gcc specific solutions are also welcomed.

Aucun commentaire:

Enregistrer un commentaire