c - 替代 ceil() 和 Floor() 来获取浮点值上方和下方最接近的整数值?

标签 c algorithm floor ceil

我正在寻找 C 中 ceil()floor() 函数的替代方案,因为我不允许在项目中使用这些函数。

到目前为止,我所构建的是一种棘手的来回方式,即使用强制转换运算符,并将浮点值(在我的例子中为 double)转换为int 及以后,因为我需要高于和低于给定浮点值的最接近的整数也是 double 值,回到 double :

#include <stdio.h>

int main(void) {
   double original = 124.576;
   double floorint;
   double ceilint;
   int f;
   int c;

   f = (int)original;            //Truncation to closest floor integer value
   c = f + 1;
   floorint = (double)f;
   ceilint = (double)c;

   printf("Original Value: %lf, Floor Int: %lf , Ceil Int: %lf", original, floorint, ceilint);
}

输出:

Original Value: 124.576000, Floor Int: 124.000000 , Ceil Int: 125.000000 

对于这个例子,通常我不需要将cf的ceil和floor整数值转换回double,但我在我的实际程序中需要将它们放在 double 中。将此视为任务的要求。

<小时/>

虽然输出给出了所需的值并且到目前为止看起来是正确的,但我仍然担心这种方法是否真的那么正确和合适,或者更清楚地说,这种方法是否确实带来了任何不良行为或问题如果还有其他可能的替代方案,那么与其他替代方案相比,我会损失性能。

<小时/>

你知道更好的选择吗?如果是这样,为什么这个应该更好?

非常感谢。

最佳答案

Do you know a better alternative? And if so, why this one should be better?

OP'代码失败:

  • original 已经是一个整数。

  • original 是一个负数,例如 -1.5。截断并不存在。

  • original 刚好超出 int 范围。

  • 原始不是数字。

<小时/>

替代结构

双 my_ceil(双 x)

当 x 超出整数范围时,使用转换为某些整数类型技巧会出现问题。因此,首先检查x是否在足够宽的整数范围内(其精度超过double)。除此以外的 x 值已经是整数。建议选择最宽的整数 (u)intmax_t

请记住,转换为整数是向 0 舍入,而不是向下取整。当代码为 ceil()floor() 时,如果 x 为负/正,则需要不同的处理。 OP 的代码错过了这一点。

我会避免使用 if (x >= INTMAX_MAX) { 因为这涉及 (double) INTMAX_MAX ,其舍入和精确值是“在实现定义中选择的”方式”。相反,我会与 INTMAX_MAX_P1 进行比较。 some_integer_MAXMersenne Number对于 2 的补码,...MIN 是“2 的幂”的负数。

#include <inttypes.h>

#define INTMAX_MAX_P1 ((INTMAX_MAX/2 + 1)*2.0)

double my_ceil(double x) {
  if (x >= INTMAX_MAX_P1) {
    return x;
  }
  if (x < INTMAX_MIN) {
    return x;
  }

  intmax_t i = (intmax_t) x;      // this rounds towards 0
  if (i < 0 || x == i) return i;  // negative x is already rounded up.
  return i + 1.0;
}

因为x可能是not-a-number ,反转比较更有用,因为 NaN 的关系比较为 false。

double my_ceil(double x) {
  if (x >= INTMAX_MIN && x < INTMAX_MAX_P1) {
    intmax_t i = (intmax_t) x;      // this rounds towards 0
    if (i < 0 || x == i) return i;  // negative x is already rounded up.
    return i + 1.0;
  }
  return x;
}

double my_floor(double x) {
  if (x >= INTMAX_MIN && x < INTMAX_MAX_P1) {
    intmax_t i = (intmax_t) x;      // this rounds towards 0
    if (i > 0 || x == i) return i;  // positive x is already rounded down.
    return i - 1.0;
  }
  return x;
}

关于c - 替代 ceil() 和 Floor() 来获取浮点值上方和下方最接近的整数值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59321732/

相关文章:

c - 不同 watch 位置同步

c - 有趣的 2 次幂 - 算法/数学(来自 Hackerrank ACM APC)

algorithm - 如何对楼层数序列求和?

上证所 SIMD 的上限/下限

与 char 和常量的比较总是失败

c++ - 具有 super 节点算法的二叉搜索树

c - 链表实现内存分配

PHP 间隔与下限

c - C语言中如何知道下一个可用的文件描述符?

c - while 在这种特殊情况下如何工作?