c++ - C++:将字符串转换为双精度
问题描述
它是用 Visual Studio 2015 编写的 C++ 代码。如下所示,
LPSTR *endPtr;
string strDouble = "0.03456";
double valDouble = strtod(strDouble.c_str(), &endPtr);
现在 valDouble 的输出是“0.0345555566”,类似这样。
我希望valDouble中的值恰好是“0.03456”。
基本上“0.0345555566”的值需要四舍五入才能说“0.03456”。
有没有办法可以实现?
顺便说一句,strDouble中的值一直在变化。所以不可能将精度设置为 5 或类似的值。下面是一些用于strDouble的示例。
string strDouble = "0.1889";
string strDouble = "0.00883342";
string strDouble = "0.2111907";
string strDouble = "3.0045";
string strDouble = "1.45";
解决方案
我希望 valDouble 中的值恰好是“0.03456”。
这是不可能的,除非您的目标是一个双浮点表示可以表示该数字的系统。
您的 CPU 可能使用的无处不在的 IEEE 754 binary64 标准中不存在 0.03456 的表示。最接近的可表示数字是 3.45600000000000004418687638008E-2。strtod
无论您使用,stod
还是字符流来转换字符串,这都是您应该得到的数字。
有没有办法可以实现?
为了在浮点不能表示该数字的系统上准确表示 0.03456,您必须使用整数来表示该数字。您可以使用整数实现任意精度算术、定点算术或十进制浮点数。
基本上值......需要四舍五入才能说“0.03456”。
将非精确浮点数转换为字符串时,可以对输出进行四舍五入:
std::cout << std::setprecision(4) << 0.03456;
顺便说一句,strDouble 中的值一直在变化。所以不可能将精度设置为 5 或类似的值。
然后,您必须记录输入字符串中的有效位数,以便在输出中使用相同的精度。
这是一个用于此目的的示例函数:
template<class Range>
auto get_precision(const Range& r)
{
auto is_significant = [](auto c) {
return std::isdigit(c) && c != '0';
};
auto first = std::find_if(std:: begin(r), std:: end(r), is_significant);
auto last = std::find_if(std::rbegin(r), std::rend(r), is_significant).base();
return std::count_if(first, last, [](auto c) {
return std::isdigit(c);
});
}
// demo
std::cout << get_precision("0.03456"); // 4
推荐阅读
- ios - Unity FIrebase 使用 Apple 登录
- angular - Angular 快速刷新从本地存储加载的项目
- python - 使用 Bazel 为 aarch64 交叉编译 tensorflow-addons
- sql - ROW_NUMBER Oracle - 奇怪的行为(添加行)
- java - 用户存储 SPI 中的 Keycloak 自定义异常
- c - 成对短字符串段比较问题的快速实现
- javascript - 如何随机使地图中的图像一张一张地出现淡入淡出?
- c++ - 显示 C++ 格式的日期
- jenkins - 与 Jenkins Crumb 值的差异
- react-native - Xcode Build failed 如果我将上传调试符号添加到哨兵脚本