c++ 如何在编译时获得大浮点数的下限

flvtvl50  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(72)

我正在用c20编写一个编译时数学库,我已经有了floor/ceiling/abs/etc.,但我目前使用的方法是n >= 0.0f ? (float)(long long)n : (float)(long long)n - 1.0f;,这是一个非常典型的快速floor函数。然而,对于大于long long max value的浮点数,这将返回垃圾,因为我将其转换为long long。我知道使用floorf适用于大型浮点数,但它不是constexpr(直到c23,仍然在预览)。然而,我不能只是复制stl正在做的事情,因为它调用了一个本身不是constexpr的内在函数。任何可以为我指出正确方向的信息都将不胜感激。

polkgigr

polkgigr1#

正如@chtz和@IgorTandetnik所述,浮点数足够大,可以大于long,long max value不能存储小数部分,因此只需返回输入。
对于浮动:

if(abs(n) > (float)(1 << 23))
{
    return n;
}
else
{
    return n >= 0.0f ? (float)(long long)n : (float)(long long)n - 1.0f;
}

字符串
双人间:

if(abs(n) > (double)(1i64 << 52))
{
    return n;
}
else
{
    return n >= 0.0 ? (double)(long long)n : (double)(long long)n - 1.0;
}


编辑:这里是一个模板化的版本与概念:

#include <type_traits>

template <std::floating_point Type>
static constexpr Type FloorF(const Type& n) noexcept
{
    static constexpr Type MaxPrecision = 1i64 << (std::numeric_limits<Type>::digits - 1);

    return n > MaxPrecision ? n :
        n >= (Type)0 ? (Type)(long long)n : (Type)(long long)n - (Type)1;
}

相关问题