Class FString: improve floating point exception handling

This commit is contained in:
Markus Gans 2015-06-30 00:21:50 +02:00
parent 36d1163343
commit 21e9e0d397
3 changed files with 22 additions and 12 deletions

View File

@ -965,7 +965,7 @@ long FString::toLong() const
if ( num > tenth_limit if ( num > tenth_limit
|| (num == tenth_limit && d > tenth_limit_digit) ) || (num == tenth_limit && d > tenth_limit_digit) )
{ {
throw std::out_of_range ("overflow"); throw std::overflow_error ("overflow");
} }
num = (num<<3)+(num<<1) + d; // (10 * num) + d num = (num<<3)+(num<<1) + d; // (10 * num) + d
p++; p++;
@ -1009,7 +1009,7 @@ uLong FString::toULong() const
if ( num > tenth_limit if ( num > tenth_limit
|| (num == tenth_limit && d > tenth_limit_digit) ) || (num == tenth_limit && d > tenth_limit_digit) )
{ {
throw std::out_of_range ("overflow"); throw std::overflow_error ("overflow");
} }
num = (num<<3)+(num<<1) + d; // (10 * num) + d num = (num<<3)+(num<<1) + d; // (10 * num) + d
p++; p++;
@ -1021,6 +1021,18 @@ uLong FString::toULong() const
return num; return num;
} }
//----------------------------------------------------------------------
float FString::toFloat() const
{
double d;
d = this->toDouble();
if ( d > FLT_MAX || d < FLT_MIN )
throw std::overflow_error ("overflow");
return float(d);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
double FString::toDouble() const double FString::toDouble() const
{ {
@ -1041,9 +1053,9 @@ double FString::toDouble() const
if ( errno == ERANGE ) if ( errno == ERANGE )
{ {
if ( ret >= HUGE_VAL || ret <= -HUGE_VAL ) if ( ret >= HUGE_VAL || ret <= -HUGE_VAL )
throw std::out_of_range ("overflow"); throw std::overflow_error ("overflow");
if ( ret == 0.0l ) if ( ret == 0.0l )
throw std::out_of_range ("underflow"); throw std::underflow_error ("underflow");
} }
return ret; return ret;
} }

View File

@ -10,6 +10,7 @@
#include <cassert> #include <cassert>
#include <cerrno> // for read errno #include <cerrno> // for read errno
#include <cfloat>
#include <climits> #include <climits>
#include <cmath> #include <cmath>
#include <cstdarg> // need for va_list, va_start and va_end #include <cstdarg> // need for va_list, va_start and va_end
@ -335,10 +336,6 @@ inline int FString::toInt() const
inline uInt FString::toUInt() const inline uInt FString::toUInt() const
{ return uInt( toULong() ); } { return uInt( toULong() ); }
//----------------------------------------------------------------------
inline float FString::toFloat() const
{ return float( toDouble() ); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline std::vector<FString> FString::split (std::wstring& s) inline std::vector<FString> FString::split (std::wstring& s)
{ return split(FString(s)); } { return split(FString(s)); }

View File

@ -140,9 +140,9 @@ int main (int, char**)
{ {
std::cerr << "Invalid argument: " << ex.what() << std::endl; std::cerr << "Invalid argument: " << ex.what() << std::endl;
} }
catch (const std::out_of_range& ex) catch (const std::exception& ex)
{ {
std::cerr << "Out of range: " << ex.what() << std::endl; std::cerr << "Arithmetic error: " << ex.what() << std::endl;
} }
setlocale(LC_NUMERIC, "C"); setlocale(LC_NUMERIC, "C");
@ -156,10 +156,11 @@ int main (int, char**)
{ {
std::cerr << "Invalid argument: " << ex.what() << std::endl; std::cerr << "Invalid argument: " << ex.what() << std::endl;
} }
catch (const std::out_of_range& ex) catch (const std::exception& ex)
{ {
std::cerr << "Out of range: " << ex.what() << std::endl; std::cerr << "Arithmetic error: " << ex.what() << std::endl;
} }
FString num1, num2, num3; FString num1, num2, num3;
num1.setNumber(137); num1.setNumber(137);
num2.setNumber(-512); num2.setNumber(-512);