它是在 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";
最佳答案
I want the value in valDouble to be exactly "0.03456".
这是不可能的,除非您的目标系统的双浮点表示法可以表示该数字。
在您的 CPU 可能使用的无处不在的 IEEE 754 二进制 64 标准中,不存在 0.03456 的表示形式。最接近的可表示数字是 3.45600000000000004418687638008E-2。无论您是使用 strtod
、stod
还是字符流来转换字符串,这都是您应该得到的数字。
Is there a way it can be achieved?
为了在 float 不能表示该数字的系统上准确表示 0.03456,您必须使用整数来表示该数字。您可以使用整数实现任意精度算术、定点算术或十进制 float 。
Basically the value ... needs to be rounded to say "0.03456".
将非精确 float 转换为字符串时,可以对输出进行舍入:
std::cout << std::setprecision(4) << 0.03456;
BTW, the value in strDouble changes all the time. So it's not possible to set precision to say 5 or something like that.
然后您必须记录输入字符串中的有效数字位数,以便在输出中使用相同的精度。
这是一个用于该目的的示例函数:
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
关于C++ : Converting String to Double,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55207450/