问题描述
小蓝最近在研究一种浮点数的表示方法:RR 格式。对于一个大于 0 的浮点数 dd,可以用 RR 格式的整数来表示。给定一个转换参数 nn,将浮点数转换为 RR 格式整数的做法是:
-
将浮点数乘以 2n2n;
-
四舍五入到最接近的整数。
输入格式
一行输入一个整数 nn 和一个浮点数 dd,分别表示转换参数,和待转换的浮点数。
输出格式
输出一行表示答案:dd 用 RR 格式表示出来的值。
样例输入
2 3.14
样例输出
13
样例说明
3.14×22=12.563.14×22=12.56,四舍五入后为 1313。
评测用例规模与约定
对于 50%50% 的评测用例:1≤n≤10,1≤1≤n≤10,1≤ 将 dd 视为字符串时的长度 ≤15≤15。
对于 100%100% 的评测用例:1≤n≤1000,1≤1≤n≤1000,1≤ 将 dd 视为字符串时的长度 ≤1024≤1024;保证 dd 是小数,即包含小数点。
代码展示
#include <iostream>
#include<cmath>
using namespace std;
int main()
{ios::sync_with_stdio(0);cin.tie(0);int n;float d;cin>>n>>d;while(n>0){d=d*2;n--;}int a=lround(d);cout<<a;// 请在此输入您的代码return 0;
}
代码功能总结
- 输入整数
n
和浮点数d
。 - 对
d
连续乘以 2 的n
次方(通过循环d = d * 2
执行n
次)。 - 将最终结果
d
四舍五入到最近的整数,输出该整数。
lround
函数详解
函数原型:
long int lround(double x); // 处理 double 类型
long int lroundf(float x); // 处理 float 类型(代码中实际调用)
long int lroundl(long double x); // 处理 long double 类型
参数:
x
:需要四舍五入的浮点数(代码中d
是float
类型,调用lroundf
)。
返回值:
- 返回四舍五入后的
long int
类型整数。 - 如果
x
超出long int
的表示范围,返回值未定义(可能返回LONG_MAX
或LONG_MIN
)。
关键行为:
- 对
x
进行四舍五入,但中间值(如 0.5)会向远离零的方向取整。
例如:lround(2.3) → 2
lround(2.5) → 3
(注意:与std::round
的行为不同!)lround(-1.7) → -2
与其他函数的区别
函数 | 返回值类型 | 舍入规则 | 用途 |
---|---|---|---|
std::round | double | 中间值向远离零方向取整 | 需要浮点结果时使用 |
lround | long int | 同上,但直接返回整数 | 需要整数且避免二次类型转换时 |
std::ceil | double | 向上取整(向正无穷方向) | 需要“不小于原数”的最小整数 |
std::floor | double | 向下取整(向负无穷方向) | 需要“不大于原数”的最大整数 |
代码中为何使用 lround
?
-
直接返回整数:
代码需要将最终结果以整数形式输出(cout << a
),使用lround
避免了额外的类型转换(例如round
返回double
,还需转换为int
)。 -
明确的四舍五入逻辑:
如果d * 2^n
的小数部分为0.5
,lround
会向更大的整数方向取整(例如2.5 → 3
),符合常见的数学四舍五入预期。
潜在问题
-
溢出风险:
如果d * 2^n
结果过大(超过long int
的范围),lround
的返回值会溢出,导致未定义行为。
改进建议:检查范围或使用try-catch
(需启用异常处理)。 -
负数的中间值处理:
对于负数中间值(如-2.5
),lround
会向更小的方向取整(即-3
),需要注意是否符合业务逻辑。
示例输入输出
-
输入:
n = 3
,d = 1.2
- 计算:
1.2 → 2.4 → 4.8 → 9.6
(乘以 2 三次) lround(9.6) → 10
- 输出:
10
- 计算:
-
输入:
n = 2
,d = 3.5
- 计算:
3.5 → 7.0 → 14.0
lround(14.0) → 14
- 输出:
14
- 计算:
总结
lround
的作用:将浮点数四舍五入到最接近的整数,直接返回long int
类型结果。- 代码逻辑:通过循环计算
d * 2^n
,并用lround
确保结果为整数。 - 注意事项:关注溢出和负数中间值的处理。