Ceil功能:我们如何自己实现?

Tim*_*oad 15 c++ ceil

我知道C++为我们提供了ceil函数.对于练习,我想知道如何在C++中实现ceil函数.该方法的签名是public static int ceil(float num)

请提供一些见解.

我想到了一个简单的方法:将num转换为字符串,找到小数点的索引,检查小数部分是否大于0.如果是,则返回num + 1,否则返回num.但我想避免使用字符串转换

fre*_*low 25

您可以拆分IEEE754浮点数的成分并自己实现逻辑:

#include <cstring>

float my_ceil(float f)
{
    unsigned input;
    memcpy(&input, &f, 4);
    int exponent = ((input >> 23) & 255) - 127;
    if (exponent < 0) return (f > 0);
    // small numbers get rounded to 0 or 1, depending on their sign

    int fractional_bits = 23 - exponent;
    if (fractional_bits <= 0) return f;
    // numbers without fractional bits are mapped to themselves

    unsigned integral_mask = 0xffffffff << fractional_bits;
    unsigned output = input & integral_mask;
    // round the number down by masking out the fractional bits

    memcpy(&f, &output, 4);
    if (f > 0 && output != input) ++f;
    // positive numbers need to be rounded up, not down

    return f;
}
Run Code Online (Sandbox Code Playgroud)

(在此插入通常的"非便携式"免责声明.)

  • 不敢相信你的答案不是被接受的答案(更不用说被接受的答案是错误的)! (2认同)

Gre*_*ill 10

这是一个正数的天真实现(这使用了将(int)截断转向零的事实):

int ceil(float num) {
    int inum = (int)num;
    if (num == (float)inum) {
        return inum;
    }
    return inum + 1;
}
Run Code Online (Sandbox Code Playgroud)

很容易将其扩展为负数.

你的问题要求函数返回int,但通常ceil()函数返回与其参数相同的类型,因此范围没有问题(即float ceil(float num)).例如,如果num是1e20 ,则上述功能将失败.

  • 鉴于大多数整数不能在流行的`float`实现中完全表示,我怀疑这是实现`ceil()`的可靠方法. (2认同)
  • @AndréCaron:这是真的,但对于这个*特定*实现来说应该不是问题,因为函数的输入不是整数. (2认同)
  • “ inum + 1”仅应用于正数。 (2认同)

Oli*_*rth 7

这基本上是你必须做的,但没有转换string.

浮点数表示为(+/-) M * 2^E.指数,E告诉你离二进制点*有多远.如果E足够大,则没有小部分,所以没有什么可做的.如果E足够小,则没有整数部分,因此答案为1(假设M为非零,且数字为正).否则,E告诉您尾数中出现二进制点的位置,您可以使用它来进行检查,然后执行舍入.


*不是小数点,因为我们在base-2,而不是base-10.

  • @Time:你可以使用`frexp()`函数来提取`M`和`E`.然后,您可以使用"E"来识别"M"中有多少位于二进制点之上,以及下面有多少位数. (2认同)

use*_*108 5

我的5美分:

template <typename F>
inline auto ceil(F const f) noexcept
{
  auto const t(std::trunc(f));

  return t + (t < f);
}
Run Code Online (Sandbox Code Playgroud)