【问题标题】:Looking for a constexpr ceil function寻找 constexpr ceil 函数
【发布时间】:2021-02-11 06:40:16
【问题描述】:

由于 std:ceil 在 Visual Studio 2015 中都不是constexpr,我正在寻找它的 constexpr 实现,我可以在编译时使用它——但收效甚微。

感谢任何帮助。

【问题讨论】:

标签: c++ c++11 visual-c++ constexpr


【解决方案1】:

由于 Visual Studio 2015 的编译器仍然不允许 constexpr 函数具有if 条件和变量,因此我重写了 Jarod42 的解决方案并将其删除:

constexpr int32_t ceil(float num)
{
    return (static_cast<float>(static_cast<int32_t>(num)) == num)
        ? static_cast<int32_t>(num)
        : static_cast<int32_t>(num) + ((num > 0) ? 1 : 0);
}

【讨论】:

  • 只是好奇。通常不赞成用浮点进行相等比较。这是一个例外吗?
  • @Flip 浮点比较如果您在正确的位置执行它们是完全可以的。在这种情况下,我们关心的是舍入后的值是否等于原始值(或者它的符号是正还是负),并且由于舍入时没有浮点错误,所以它是浮点相等的正确位置。如果你想解决以前计算产生的浮点错误,那么你需要修改这个函数来处理这个问题。
  • 我在我的 (GPL3) 库中使用了这个,希望没问题;)。
  • @CarloWood 当然,谢谢提及。图书馆的名字是什么?我只是好奇。
【解决方案2】:

你可以使用

constexpr std::int32_t ceil(float num) {
    std::int32_t inum = static_cast<std::int32_t>(num);
    if (num == static_cast<float>(inum)) {
        return inum;
    }
    return inum + (num > 0 ? 1 : 0);
}

Live demo

注意:一旦整数不能表示浮点值,它就不起作用。

【讨论】:

  • 为什么不像std提供的那样float ceil(float);
  • @legends2k:此实现不适用于所有浮点值,签名反映了这一点。
【解决方案3】:

这是一个基于Jarod42's excellent answer 的版本,消除了两个分支之一。这适用于 C++14 或 C++17——如果你内联整数转换,你可以让它也支持 C++11。

constexpr int int_ceil(float f)
{
    const int i = static_cast<int>(f);
    return f > i ? i + 1 : i;
}

这是一个用于验证正确行为的小套件。 (只是一系列 C++17 static_assert()s,因为函数是 constexpr——如果它编译,你就知道测试通过了!)

static_assert(int_ceil(0.0) == 0);
static_assert(int_ceil(0.5) == 1);
static_assert(int_ceil(0.999999) == 1);
static_assert(int_ceil(1.0) == 1);
static_assert(int_ceil(123.0) == 123);
static_assert(int_ceil(123.4) == 124);

static_assert(int_ceil(-0.5) == 0);
static_assert(int_ceil(-0.999999) == 0);
static_assert(int_ceil(-1.0) == -1);
static_assert(int_ceil(-123.0) == -123);
static_assert(int_ceil(-123.4) == -123);

Here's a Compiler Explorer sample 一起玩(作为奖励,它还包括floor()constexpr 实现)。

【讨论】:

    猜你喜欢
    • 2020-02-10
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多