我正在考虑floor可用的功能math.h.它很容易使用:
#include <stdio.h>
#include <math.h>
int main(void)
{
for (double a = 12.5; a < 13.4; a += 0.1)
printf("floor of %.1lf is %.1lf\n", a, floor(a));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我想编写自己的实现怎么办?看起来像这样:
#include <stdio.h>
#include <math.h>
double my_floor(double num)
{
return (int)num;
}
int main(void)
{
double a;
for (a = 12.5; a < 13.4; a += 0.1)
printf("floor of %.1lf is %.1lf\n", a, floor(a));
printf("\n\n");
for (a = 12.5; a < 13.4; a += 0.1)
printf("floor of %.1lf is %.1lf\n", a, my_floor(a));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
?
它似乎不适用于负数(my_floor),但第二个看起来很好(my_floor_2):
#include <stdio.h>
#include <math.h>
double my_floor(double num)
{
return (int)num;
}
double my_floor_2(double num)
{
if(num < 0)
return (int)num - 1;
else
return (int)num;
}
int main(void)
{
double a1 = -12.5;
printf("%lf\n", floor(a1));
printf("%lf\n", my_floor(a1));
printf("%lf\n", my_floor_2(a1));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
程序输出:

其中一个最终是否正确?
您的两种尝试都有局限性:
double值超出类型的范围int,则转换为int实现定义的。double值为负数但为整数,则返回(int)num - 1不正确。这是一个(几乎)可移植的版本,尝试处理所有情况:
double my_floor_2(double num) {
if (num >= LLONG_MAX || num <= LLONG_MIN || num != num) {
/* handle large values, infinities and nan */
return num;
}
long long n = (long long)num;
double d = (double)n;
if (d == num || num >= 0)
return d;
else
return d - 1;
}
Run Code Online (Sandbox Code Playgroud)
long long如果 type 的值位多于 type ,那么它应该是正确的(double大多数现代系统都是这种情况)。
不,你不能这样解决它.编写自己的实现的最佳方法是从平台上的C标准库中窃取一个.但请注意,可能包含特定于平台的细微差别,因此可能无法移植.
C标准库floor函数通常很聪明,因为它不能通过转换为整数类型来工作.如果确实如此,那么您将面临signed整数溢出的风险,其行为未定义.(请注意,a的最小可能范围int是-32767到+32767).
精确实现还取决于平台上使用的浮点方案.
对于使用IEEE754浮点的平台和long long类型,您可以采用此方案: