C++ 安全读取溢出双as';inf&x27;从字符串
是否有一种很好的方法可以从字符串中读取溢出的C++ 安全读取溢出双as';inf&x27;从字符串,c++,double,ieee-754,C++,Double,Ieee 754,是否有一种很好的方法可以从字符串中读取溢出的double,即转换“1e500”->+inf 我知道的读取字符串的方法: ::std::stringstream-溢出时返回垃圾 ::boost::lexical\u cast-抛出错误的\u lixecal\u cast,没有关于正在转换的数字的有用信息 ::std::strtodfromcstdlib-afaik它是唯一一个报告溢出的软件(通过返回大数值并将错误号设置为Errange),但是使用它非常不方便 特别是我需要一种方法来可靠地将字符
double
,即转换“1e500”->+inf
我知道的读取字符串的方法:
-溢出时返回垃圾李>::std::stringstream
-抛出错误的\u lixecal\u cast,没有关于正在转换的数字的有用信息::boost::lexical\u cast
from::std::strtod
-afaik它是唯一一个报告溢出的软件(通过返回cstdlib
大数值
并将
错误号
设置为
),但是使用它非常不方便Errange
double
),例如
编辑:
我实际上使用的是最后一种方法,下面是代码:
double stringToDouble(char const *str)
{
double result = ::std::strtod(str, 0);
if (ERANGE == errno)
{
if (HUGE_VAL == result)
{
result = INFINITY;
}
else if (-HUGE_VAL == result)
{
result = -INFINITY;
}
}
return result;
}
我很惊讶stringstream
不能很好地处理溢出。但它实际上返回了一些其他的双
值(与正在读取的值无关),并且只按stream::fail()方式报告
<>但是我仍然在寻找一些C++的方式读取数字。 嗯,你当前的C方式比我所建议的要有效得多,但是既然你要C++,那么这里有一个定义机械手类对象来保护你不溢出:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <limits>
#include <algorithm>
using namespace std;
struct OverflowProtect
{
} limitdouble;
struct DoubleOverflowException : public std::exception
{
};
double stringToDouble(char const *str)
{
double result = ::std::strtod(str, 0);
if (ERANGE == errno)
{
if (HUGE_VAL == result)
{
throw DoubleOverflowException(); // throw whatever exception you want here
}
else if (-HUGE_VAL == result)
{
throw DoubleOverflowException(); // throw whatever exception you want here
}
}
return result;
}
istream & operator >> (istream & aIn, const OverflowProtect & aManip)
{
string number;
aIn >> number;
stringToDouble(number.c_str());
for_each(number.rbegin(), number.rend(), [&aIn](char c){aIn.putback(c);});
return aIn;
}
int _tmain(int argc, _TCHAR* argv[])
{
double nr;
try
{
cin >> limitdouble >> nr;
}
catch ( DoubleOverflowException & e )
{
// handle overflow exception thrown by limitdouble
e;
}
return 0;
}
#包括“stdafx.h”
#包括
#包括
#包括
#包括
使用名称空间std;
结构溢出保护
{
}有限双倍;
结构DoubleOverflowException:public std::exception
{
};
双字符串双字符(字符常量*str)
{
双结果=::std::strtod(str,0);
if(ERANGE==errno)
{
如果(巨大值==结果)
{
抛出DoubleOverflowException();//在这里抛出您想要的任何异常
}
else if(-maging_VAL==结果)
{
抛出DoubleOverflowException();//在这里抛出您想要的任何异常
}
}
返回结果;
}
istream和operator>>(istream和aIn、常数溢出保护和aManip)
{
字符串编号;
aIn>>编号;
stringToDouble(number.c_str());
对于每个(number.rbegin(),number.rend(),[&aIn](字符c){aIn.putback(c);});
返回aIn;
}
int _tmain(int argc,_TCHAR*argv[]
{
双nr;
尝试
{
cin>>limitdouble>>nr;
}
捕获(双重溢出例外和e)
{
//limitdouble引发的句柄溢出异常
E
}
返回0;
}
不是最有效的方法,尤其是操作符>>
实现,但毫无疑问,它很喜欢C++,而且很有趣。
我确信可以进行改进,我只是说明一个想法。好的,使用strtod,将不方便之处包装在函数中,这样就不会带来不便了,不是吗?你确定没有办法让istringstream以某种方式报告这些数字的错误吗?它返回的垃圾到底是什么?@John:是的,但是提供一个代码示例怎么样?这对你来说可能很明显,但对OP来说却不明显,否则他不会问的。@RobertHarvey我不确定你是否正确。但无论如何,我只是在评论,而不是提供答案。如果OP需要一些代码,我很乐意给它。@john我现在实际上正在使用这个解决方案,但我正在寻找一些C++,这确实很有趣。:)
#include "stdafx.h"
#include <iostream>
#include <string>
#include <limits>
#include <algorithm>
using namespace std;
struct OverflowProtect
{
} limitdouble;
struct DoubleOverflowException : public std::exception
{
};
double stringToDouble(char const *str)
{
double result = ::std::strtod(str, 0);
if (ERANGE == errno)
{
if (HUGE_VAL == result)
{
throw DoubleOverflowException(); // throw whatever exception you want here
}
else if (-HUGE_VAL == result)
{
throw DoubleOverflowException(); // throw whatever exception you want here
}
}
return result;
}
istream & operator >> (istream & aIn, const OverflowProtect & aManip)
{
string number;
aIn >> number;
stringToDouble(number.c_str());
for_each(number.rbegin(), number.rend(), [&aIn](char c){aIn.putback(c);});
return aIn;
}
int _tmain(int argc, _TCHAR* argv[])
{
double nr;
try
{
cin >> limitdouble >> nr;
}
catch ( DoubleOverflowException & e )
{
// handle overflow exception thrown by limitdouble
e;
}
return 0;
}