C:如何将 float 包装到区间 [-pi, pi)

标签 c math floating-point intervals modulo

我正在寻找一些可以有效完成的不错的 C 代码:

while (deltaPhase >= M_PI) deltaPhase -= M_TWOPI;
while (deltaPhase < -M_PI) deltaPhase += M_TWOPI;

我有哪些选择?

最佳答案

2013 年 4 月 19 日编辑:

Modulo 函数已更新以处理边界情况,如 aka.nice 和 arr_sea 所述:

static const double     _PI= 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348;
static const double _TWO_PI= 6.2831853071795864769252867665590057683943387987502116419498891846156328125724179972560696;

// Floating-point modulo
// The result (the remainder) has same sign as the divisor.
// Similar to matlab's mod(); Not similar to fmod() -   Mod(-3,4)= 1   fmod(-3,4)= -3
template<typename T>
T Mod(T x, T y)
{
    static_assert(!std::numeric_limits<T>::is_exact , "Mod: floating-point type expected");

    if (0. == y)
        return x;

    double m= x - y * floor(x/y);

    // handle boundary cases resulted from floating-point cut off:

    if (y > 0)              // modulo range: [0..y)
    {
        if (m>=y)           // Mod(-1e-16             , 360.    ): m= 360.
            return 0;

        if (m<0 )
        {
            if (y+m == y)
                return 0  ; // just in case...
            else
                return y+m; // Mod(106.81415022205296 , _TWO_PI ): m= -1.421e-14 
        }
    }
    else                    // modulo range: (y..0]
    {
        if (m<=y)           // Mod(1e-16              , -360.   ): m= -360.
            return 0;

        if (m>0 )
        {
            if (y+m == y)
                return 0  ; // just in case...
            else
                return y+m; // Mod(-106.81415022205296, -_TWO_PI): m= 1.421e-14 
        }
    }

    return m;
}

// wrap [rad] angle to [-PI..PI)
inline double WrapPosNegPI(double fAng)
{
    return Mod(fAng + _PI, _TWO_PI) - _PI;
}

// wrap [rad] angle to [0..TWO_PI)
inline double WrapTwoPI(double fAng)
{
    return Mod(fAng, _TWO_PI);
}

// wrap [deg] angle to [-180..180)
inline double WrapPosNeg180(double fAng)
{
    return Mod(fAng + 180., 360.) - 180.;
}

// wrap [deg] angle to [0..360)
inline double Wrap360(double fAng)
{
    return Mod(fAng ,360.);
}

关于C:如何将 float 包装到区间 [-pi, pi),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4633177/

相关文章:

c++ - Visual Studio C++ 调试包含静态库的 DLL

algorithm - 解决复发

algorithm - 在球冠上找到均匀分布的随机点

c++ - e+000是几号?

c - 为什么 FLT_MIN 等于零?

c++ - 如何检查给定进程在运行时加载了哪些共享库?

C 程序 - 结构指针

c - 迭代控制循环无法正常工作

perl - Perl 中浮点等效的单元测试

java - 在 Java 中表示浮点值