Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
可以选择ceil()和floor()来获取最接近的整数值,在浮点值的上方和下方?_C_Algorithm_Floor_Ceil - Fatal编程技术网

可以选择ceil()和floor()来获取最接近的整数值,在浮点值的上方和下方?

可以选择ceil()和floor()来获取最接近的整数值,在浮点值的上方和下方?,c,algorithm,floor,ceil,C,Algorithm,Floor,Ceil,我正在为C中的ceil()和floor()函数寻找一种替代方法,因为我不允许在项目中使用这些函数 到目前为止,我所构建的是一种复杂的来回转换方式,通过使用cast运算符,将浮点值(在我的例子中是double)转换为int,然后我需要最接近的整数,在给定浮点值的上方和下方,也就是double值,返回到双倍 #include <stdio.h> int main(void) { double original = 124.576; double floorint; d

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

到目前为止,我所构建的是一种复杂的来回转换方式,通过使用cast运算符,将浮点值(在我的例子中是
double
)转换为
int
,然后我需要最接近的整数,在给定浮点值的上方和下方,也就是
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);
}
对于本例,通常我不需要将
c
f
的ceil和floor整数值转换回
double
,但在实际程序中,我需要它们位于
double
中。将此视为任务的要求。


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


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


非常感谢。

您错过了一个重要步骤:您需要检查数字是否已经是整数,因此对于
ceil
假设非负数(泛化很简单),请使用

double ceil(double f){
    if (f >= LLONG_MAX){
        // f will be integral unless you have a really funky platform
        return f;
    } else {
        long long i = f;
        return 0.0 + i + (f != i); // to obviate potential long long overflow
    }
}
拼图中的另一个缺失部分是检查
f
是否在
long
的范围内,这一点已被我随函附上的
if
所覆盖。在通用平台上,如果
f
超出了
long
的界限,那么它无论如何都是整数

请注意,
floor
是微不足道的,因为对
long
的截断总是接近零

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

操作代码失败:

  • original
    已经是一个整数

  • original
    是负片,类似于
    -1.5
    。截断不存在

  • original
    刚好在
    int
    范围之外

  • 原件
    不是数字


替代结构

双倍我的手机(双倍x)

x
超出整数范围时,对某些整数类型使用强制转换技巧是一个问题。因此,首先检查
x
是否在足够宽的整数范围内(精度超过
double
x
值超出已为整数的范围。建议选择最宽的整数
(u)intmax\u t

请记住,对整数的转换是朝向0的圆,而不是地板。当代码为
ceil()
floor()
时,如果
x
为负/正,则需要进行不同的处理。OP的密码漏掉了这个

如果(x>=INTMAX\u MAX){涉及的
(double)INTMAX\u MAX
的四舍五入和精确值是“以实现定义的方式选择的”,我会避免
,相反,我会与
INTMAX\u MAX\u P1
进行比较,一些整数\u MAX
是a,如果是2的补码,
…MIN
是一个否定的值“2的力量”


\u mm\u round\u sd
如果seriously@Sopel我该怎么处理
\u mm\u round\u sd
?@RobertS,如果输入是124怎么办!!!!@ManthanTilva好吧,我想,你是对的,我应该提供一个条件,如果原始值为“真”,ceil值只能是地板值的+1“浮点值。否则ceil值应该与下限值相等。对于下限值,在这种情况下应该没有重要区别。@RobertS:当然。这就是表达式
0.0+i+(f!=i)的含义。”
在我的回答中是这样的。首先非常感谢你的回答。为什么这两件事对这个案例如此重要?为什么我忽略它们会很糟糕?这对我来说不是很清楚。~@RobertS:我现在的版本很好,假设64位IEEE754浮点双精度。还有一个难题是如何处理NaNs和infi缺点。@th33lf:的确。编写一个可移植的
ceil
是一件痛苦的事。C标准库很容易忽略可移植性。但是你仍然应该将上面的测试改为if(f=LLONG_MAX){….非常感谢你的深入解释。是的,这就是我所要求的,因为作为一个初学者,我不知道所有的情况。我需要一段时间来完成单独的步骤并详细理解它们。非常感谢你,chux!@chqrlie是的-那更好。
double ceil(double f){
    if (f >= LLONG_MAX){
        // f will be integral unless you have a really funky platform
        return f;
    } else {
        long long i = f;
        return 0.0 + i + (f != i); // to obviate potential long long overflow
    }
}
#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;
}
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;
}