gpt4 book ai didi

c++ - atof 和 stringstream 产生不同的结果

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:43:34 25 4
gpt4 key购买 nike

我一直在研究将 float 转换为人类可读格式并返回的问题。即一个字符串。我在使用 stringstream 时遇到了问题,发现 atof 产生了“更好”的结果。

注意,在这种情况下我没有打印出数据,我使用调试器检索值:

    const char *val = "73.31";
std::stringstream ss;
ss << val << '\0';
float floatVal = 0.0f;
ss >> floatVal; //VALUE IS 73.3100052

floatVal = atof(val); //VALUE IS 73.3099976

对此可能有一个合理的解释。如果有人能启发我,我将不胜感激 :)。

最佳答案

答案基于OP使用MSVC的假设

atof 在读取浮点值方面确实比 istream 更好。

看这个例子:

#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstdlib>

int main()
{
const char *val = "73.31";
std::stringstream ss;
ss << val;
float floatVal = 0.0f;
ss >> floatVal;
std::cout << "istream>>(float&) :" << std::setw(18) << std::setprecision(15) << floatVal << std::endl;

double doubleVal = atof(val);
std::cout << "double atof(const char*) :" << std::setw(18) << std::setprecision(15) << doubleVal << std::endl;

floatVal = doubleVal;
std::cout << "(float)double atof(const char*) :" << std::setw(18) << std::setprecision(15) << floatVal << std::endl;

doubleVal = floatVal;
std::cout << "(double)(float)double atof(const char*) :" << std::setw(18) << std::setprecision(15) << floatVal << std::endl;
}

输出:

istream>>(float&)                       :  73.3100051879883
double atof(const char*) : 73.31
(float)double atof(const char*) : 73.3099975585938
(double)(float)double atof(const char*) : 73.3099975585938

编译器甚至会警告从 doublefloat 的转换:

warning C4244: '=': conversion from 'double' to 'float', possible loss of data

我还找到了这个页面:Conversions from Floating-Point Types


更新:

73.3099975585938 似乎是 double73.31 的正确 float 解释。


更新:istream>>(double&) 也能正常工作:

#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstdlib>

int main()
{
const char *val = "73.31";
std::stringstream ss;
ss << val;
double doubleVal = 0.0f;
ss >> doubleVal;
std::cout << "istream>>(double&) :" << std::setw(18) << std::setprecision(15) << doubleVal << std::endl;
}

输出:

istream>>(double&) :             73.31

对于算术类型 istream::operator>> 使用 num_get::getnum_get::get 应该为 float 使用类似 scanf("%g") 的东西 source

但是:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <iomanip>
#include <cstdlib>


int main()
{
std::string s = "73.31";
float f = 0.f;
sscanf(s.c_str(), "%g", &f);
std::cout << std::setw(18) << std::setprecision(15) << f << std::endl;
}

输出:

73.3099975585938

对我来说,这看起来像是 Microsoft num_get 中的错误

关于c++ - atof 和 stringstream 产生不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32495453/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com