文章目录
- 💯前言
- 💯ceil 和 floor 函数的基础介绍
- 1. ceil 函数
- 定义与功能
- 示例代码
- 输出结果
- 功能分析
- 使用场景
- 2. floor 函数
- 定义与功能
- 示例代码
- 输出结果
- 功能分析
- 使用场景
- 💯自行实现 ceil 和 floor 函数
- 1. 自行实现 ceil 函数
- 代码实现
- 示例输入输出
- 优化
- 2. 自行实现 floor 函数
- 代码实现
- 示例输入输出
- 💯`(int)` 类型转换的局限性
- 具体原因
- 示例
- 💯小结
💯前言
- 在日常的编程任务中,处理浮点数的向上取整和向下取整是一个非常常见的需求。C++ 提供了强大的数学库
<cmath>
,其中包含了ceil
和floor
函数,分别用于实现向上取整和向下取整的功能。然而,有些场景可能需要我们自行实现这些功能,以便深入理解其底层逻辑,或者针对某些特殊需求进行优化和扩展。
本文将通过代码实例详细分析ceil
和floor
的功能、实现思路及其扩展,包括自行实现的方式。同时,针对读者可能会遇到的问题,比如(int)
类型转换的局限性,我们也会进行详细说明,并提供相应的解决方案。
C++ 参考手册
💯ceil 和 floor 函数的基础介绍
1. ceil 函数
定义与功能
ceil
(向上取整)是一个数学函数,它的作用是将一个浮点数向上取整为大于等于它的最小整数。
示例代码
以下是使用标准库 ceil
函数的代码示例:
#include <iostream>
#include <cmath>
using namespace std;int main()
{cout << ceil(2.3) << endl; // 输出: 3cout << ceil(3.8) << endl; // 输出: 4cout << ceil(-2.3) << endl; // 输出: -2cout << ceil(-3.8) << endl; // 输出: -3return 0;
}
输出结果
3
4
-2
-3
功能分析
- 对正数:
ceil
会向上取整到最近的更大整数。例如,2.3
向上取整为3
,3.8
向上取整为4
。 - 对负数:
ceil
会向上取整到更接近零的整数。例如,-2.3
向上取整为-2
,-3.8
向上取整为-3
。
使用场景
ceil
常用于需要确保数值“至少达到某个值”的场景,比如:
- 计算物品的最少包装数量。
- 计算天数时,向上取整到完整的天数。
2. floor 函数
定义与功能
floor
(向下取整)是一个数学函数,它的作用是将一个浮点数向下取整为小于等于它的最大整数。
示例代码
以下是使用标准库 floor
函数的代码示例:
#include <iostream>
#include <cmath>
using namespace std;int main()
{cout << floor(2.3) << endl; // 输出: 2cout << floor(3.8) << endl; // 输出: 3cout << floor(-2.3) << endl; // 输出: -3cout << floor(-3.8) << endl; // 输出: -4return 0;
}
输出结果
2
3
-3
-4
功能分析
- 对正数:
floor
会向下取整到最近的更小整数。例如,2.3
向下取整为2
,3.8
向下取整为3
。 - 对负数:
floor
会向下取整到更远离零的整数。例如,-2.3
向下取整为-3
,-3.8
向下取整为-4
。
使用场景
floor
常用于需要确保数值“不超过某个值”的场景,比如:
- 分配预算,确保不超出限额。
- 对数据进行分组,向下取整到某个区间。
💯自行实现 ceil 和 floor 函数
1. 自行实现 ceil 函数
自行实现 ceil
的核心在于判断浮点数的小数部分是否大于 0。如果大于 0,则将整数部分加 1;否则直接返回整数部分。
代码实现
#include <iostream>
using namespace std;int main() {double d = 0; // 声明一个双精度浮点数并初始化为0cin >> d; // 输入一个浮点数int q = (int)d; // 提取浮点数的整数部分double p = d - q; // 计算浮点数的小数部分if (p > 0.0) // 如果小数部分大于 0cout << (int)(d + 1); // 输出向上取整后的整数elsecout << (int)d; // 否则直接输出整数部分return 0;
}
示例输入输出
-
输入:
3.14
- 整数部分:
3
- 小数部分:
0.14
- 输出:
4
- 整数部分:
-
输入:
5.00
- 整数部分:
5
- 小数部分:
0
- 输出:
5
- 整数部分:
-
输入:
-2.7
- 整数部分:
-2
- 小数部分:
-0.7
- 输出:
-2
- 整数部分:
优化
为了更清晰地表达逻辑,我们可以将代码封装为函数:
int myCeil(double d) {int q = (int)d;if (d - q > 0.0)return q + 1;return q;
}
2. 自行实现 floor 函数
自行实现 floor
的核心在于处理负数的特殊情况。如果是负数且存在小数部分,则需要向更小的整数方向取整。
代码实现
#include <iostream>
using namespace std;int main() {double d = 0;cin >> d;if (d >= 0) {cout << (int)d << endl; // 正数直接取整数部分} else {if (d == (int)d) {cout << (int)d << endl; // 如果是负整数,直接输出} else {cout << (int)(d - 1) << endl; // 负数向下取整}}return 0;
}
示例输入输出
- 输入:
3.14
- 输出:
3
- 输出:
- 输入:
-3.14
- 输出:
-4
- 输出:
💯(int)
类型转换的局限性
在讨论 ceil
和 floor
的实现时,(int)
强制类型转换是一个常见的手段,但它并不完全等同于 ceil
或 floor
,特别是在处理负数时。
具体原因
(int)
强制类型转换会直接截断小数部分(舍弃小数部分),相当于向零方向取整。- 对正数:效果等同于
floor
。 - 对负数:效果既不等同于
ceil
,也不等同于floor
。
示例
输入值 | (int) 转换 | ceil 结果 | floor 结果 |
---|---|---|---|
3.14 | 3 | 4 | 3 |
-3.14 | -3 | -3 | -4 |
💯小结
ceil
和floor
是 C++ 中处理浮点数取整的两个重要函数,其核心在于处理小数部分的舍入方式。(int)
强制转换可以用于简单的取整,但在负数场景下需要特别注意。- 自行实现
ceil
和floor
的过程能够帮助我们更好地理解这两个函数的逻辑,同时也能根据实际需求进行定制。
建议在实际开发中,优先使用标准库函数 ceil
和 floor
,它们经过高度优化并且能够处理更多边界情况。