C++ 将字符串转换为双精度时出现算术错误
我正在编写一个函数,将用户提供的字符串转换为double。它对某些值非常有效,但对其他值无效。比如说C++ 将字符串转换为双精度时出现算术错误,c++,string,double,C++,String,Double,我正在编写一个函数,将用户提供的字符串转换为double。它对某些值非常有效,但对其他值无效。比如说 string_to_double("123.45") = 123.45 string_to_double(12345) = 12345 但是 我相当确定这是某种舍入误差,但我没有使用近似值,也没有使用非常小或非常大的值。我的问题有两个方面:为什么我会得到这些奇怪的结果?如何更改代码以获得更准确的结果?我这样做也是个人的挑战,所以建议使用诸如std::stod之类的方法是没有帮助的。我相信问题发
string_to_double("123.45") = 123.45
string_to_double(12345) = 12345
但是
我相当确定这是某种舍入误差,但我没有使用近似值,也没有使用非常小或非常大的值。我的问题有两个方面:为什么我会得到这些奇怪的结果?如何更改代码以获得更准确的结果?我这样做也是个人的挑战,所以建议使用诸如std::stod
之类的方法是没有帮助的。我相信问题发生在第二个for循环中,但我觉得包含整个方法是明智的,因为如果我遗漏了一些内容,那么就不会有太多额外的代码需要阅读
我的代码
template <class T>
double numerical_descriptive_measures<T>::string_to_double(std::string user_input)
{
double numeric_value = 0;//Stores numeric value of string. Return value.
int user_input_size = user_input.size();
int power = 0;
/*This loop is for the characteristic portion of the input
once this loop finishes, we know what to multiply the
characterstic portion by(e.g. 1234 = 1*10^3 + 2*10^2 + 3*10^1 + 4)
*/
for(int i = 0;i < user_input_size;i++)
{
if(user_input[i] == '.')
break;
else
power++;
}
/*This loop is for the mantissa. If this portion is zero,
the loop doesn't execute because i will be greater than
user_input_size.*/
for(int i = 0;i < user_input_size;i++)
{
if(user_input[i] != '.')
{
numeric_value += ((double)user_input[i] - 48.0)*pow(10,power-i-1);
}
else
{
double power = -1.0;
for(int j = i+1;j < user_input_size;j++)
{
numeric_value += ((double)user_input[j] - 48.0)*pow(10.0,power);
power = power-1.0;
}
break;
}
}
return numeric_value;
}
模板
双数值\描述性\度量::字符串\到\双(标准::字符串用户\输入)
{
double numeric_value=0;//存储字符串的数值。返回值。
int user_input_size=user_input.size();
整数幂=0;
/*该回路用于输入的特征部分
一旦这个循环完成,我们就知道要将
字符部分by(例如1234=1*10^3+2*10^2+3*10^1+4)
*/
对于(int i=0;i
问题不在于生成了错误的浮点值,而在于打印精度不够:
std::cout<<data<<std::endl
std::cout问题不在于生成了错误的浮点值,而在于打印精度不够:
std::cout<<data<<std::endl
std::cout您的代码没有为“123.4567”生成不正确的值,但通常会生成不正确的值。例如,字符串_to_double(“0.0012”)产生(在Visual Studio 2015上)
0.0012000000000117161918529063768801279660163879339453125
但正确的答案是
0.001199999999999894875735580549007863737642765045166166015625
(您必须将它们打印到17位有效数字才能看出差异。)
问题是不能使用浮点转换为浮点——一般来说,它没有足够的精度
(我在我的网站上写了很多关于这一点的文章;例如,请参阅和。)您的代码没有为“123.4567”生成不正确的值,但通常会生成不正确的值。例如,字符串_to_double(“0.0012”)产生(在Visual Studio 2015上)
0.0012000000000117161918529063768801279660163879339453125
但正确的答案是
0.001199999999999894875735580549007863737642765045166166015625
(您必须将它们打印到17位有效数字才能看出差异。)
问题是不能使用浮点转换为浮点——一般来说,它没有足够的精度
(我在我的网站上写了很多关于这方面的文章;例如,请参阅和。)你确定这个值真的是123.457吗?你怎么印的?可能打印功能只是将其四舍五入。还有,你为什么要重新发明这个轮子?@JohnZwinck我正在用std::coutar打印这个函数你确定这个值真的是123.457吗?你怎么印的?可能打印功能只是将其四舍五入。还有,你为什么要重新发明这个轮子?@JohnZwinck我正在用std::cout打印这个函数。虽然代码通常会产生不正确的值——请看我的答案。但是代码通常会产生不正确的值——请看我的答案。