提问人:Lee 提问时间:11/13/2022 最后编辑:Lee 更新时间:11/14/2022 访问量:203
在字符串流中使用固定和设置精度时 C++ 的轮次误差
round error of C++ when using fixed and setprecision in stringstream
问:
我用 C++ 编写了一个程序,我认为它的结果应该是 12.3 和 12.2。但最终结果是 12.2 和 12.2。显然,它没有正确四舍五入。但是为什么? 非常感谢你:)
#include <iostream>
#include <iomanip>
using namespace std;
string dtos(double num) {
stringstream ss;
ss << fixed << setprecision(1) << num;
return ss.str();
}
int main() {
double num1 = 12.25;
double num2 = 12.24;
string str1 = dtos(num1);
string str2 = dtos(num2);
cout << str1 << ' ' << str2 << endl;
return 0;
}
我还尝试了 num1 = 12.05 和 num2 = 12.04 的方法,并获得所需的结果为 12.1 和 12.0。
答:
3赞
shy45
11/14/2022
#1
我检查了每个圆形函数的特征。因此,基本上这些函数从值返回最接近的整数,但如果该值位于两个整数之间的中间位置,则有以下行为类型可供计算。
- 舍入类型
- NI:最接近的整数,远不为零。(例如 2.5 -> 3)
- NE:与值最接近的偶数。(例如 2.5 -> 2)
- 中途型
- 确切地说:考虑浮点误差。(例如,2.500002 不是中途)
- 不完全是:忽略浮点错误。(例如,2.500002 被视为 2.5)
这就是为什么每个功能可以分为以下几种类型的原因。
SetPrecision(设置精度)
- 舍入类型:NE
- 中途型:正好
林特
- 舍入类型:NE
- 中途类型:不完全是
圆
- 舍入类型:NI
- 中途类型:不完全是
#include <iostream>
#include <cfenv>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
fesetround(FE_TONEAREST);
//fesetround(FE_DOWNWARD);
//fesetround(FE_UPWARD);
printf("round type=%d\n\n", fegetround());
auto f = [&](auto v) {
printf("%-14s %.30f\n", "orig val", v);
cout << fixed << "setprecision" << setw(7) << setprecision(1) << v << endl;
printf("%-14s %.30f\n", "rint", rint((v * 10)) / 10);
printf("%-14s %.30f\n", "round", round((v * 10)) / 10);
cout << "-----------------" << endl;
};
f(12.05);
f(12.25);
f(12.35);
f(12.75);
}
输出为
round type=0
orig val 12.050000000000000710542735760100
setprecision 12.1
rint 12.000000000000000000000000000000
round 12.099999999999999644728632119950
-----------------
orig val 12.250000000000000000000000000000
setprecision 12.2
rint 12.199999999999999289457264239900
round 12.300000000000000710542735760100
-----------------
orig val 12.349999999999999644728632119950
setprecision 12.3
rint 12.400000000000000355271367880050
round 12.400000000000000355271367880050
-----------------
orig val 12.750000000000000000000000000000
setprecision 12.8
rint 12.800000000000000710542735760100
round 12.800000000000000710542735760100
-----------------
评论
0赞
Lee
11/14/2022
谢谢,我认为这就是答案。
评论
12.05
12.1