Class FString: Add toFloat(), toDouble() and setNumber(...) for floating point values

This commit is contained in:
Markus Gans 2015-06-27 23:00:12 +02:00
parent c4fbad06ca
commit f9001e59de
7 changed files with 124 additions and 34 deletions

View File

@ -21,7 +21,6 @@ Missing Features
--------------------------------------- ---------------------------------------
- Multiple lines support for FLabel - Multiple lines support for FLabel
- long double to FString + FString to long double
- Add a window switcher on the right side of the status bar - Add a window switcher on the right side of the status bar
- Add a scrolling area with on-demand scroll bars for FButtonGroup - Add a scrolling area with on-demand scroll bars for FButtonGroup

View File

@ -27,6 +27,7 @@ typedef signed short sInt16;
typedef signed int sInt32; typedef signed int sInt32;
typedef int64_t sInt64; typedef int64_t sInt64;
typedef long double lDouble;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// class FObject // class FObject

View File

@ -1017,6 +1017,30 @@ uLong FString::toULong() const
return num; return num;
} }
//----------------------------------------------------------------------
double FString::toDouble() const
{
wchar_t* p;
register double ret;
if ( ! this->string || ! *this->string )
throw std::invalid_argument ("null value");
ret = wcstod(this->string, &p);
if ( p != 0 && *p != '\0' )
throw std::invalid_argument ("no valid floating point value");
if ( errno == ERANGE )
{
if ( ret >= HUGE_VAL || ret <= -HUGE_VAL )
throw std::out_of_range ("overflow");
if ( ret == 0.0l )
throw std::out_of_range ("underflow");
}
return ret;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FString FString::ltrim() const FString FString::ltrim() const
{ {
@ -1212,6 +1236,34 @@ FString& FString::setNumber (uLong num)
return *this; return *this;
} }
//----------------------------------------------------------------------
FString& FString::setNumber (lDouble num, int precision)
{
register wchar_t *s;
wchar_t format[20]; // = "%.<precision>Lg"
s = &format[0];
*s++ = L'%';
*s++ = L'.';
if ( precision > 99 )
precision = 99;
if ( precision >= 10 )
{
*s++ = precision / 10 + L'0';
*s++ = precision % 10 + L'0';
}
else
*s++ = precision + L'0';
*s++ = L'L';
*s++ = L'g';
*s = L'\0';
return sprintf(format, num);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FString& FString::setFormatedNumber (long num, char separator) FString& FString::setFormatedNumber (long num, char separator)
{ {

View File

@ -11,6 +11,7 @@
#include <cassert> #include <cassert>
#include <cerrno> // for read errno #include <cerrno> // for read errno
#include <climits> #include <climits>
#include <cmath>
#include <cstdarg> // need for va_list, va_start and va_end #include <cstdarg> // need for va_list, va_start and va_end
#include <cstdio> // need for vsprintf #include <cstdio> // need for vsprintf
#include <cstring> #include <cstring>
@ -44,6 +45,8 @@ typedef signed short sInt16;
typedef signed int sInt32; typedef signed int sInt32;
typedef int64_t sInt64; typedef int64_t sInt64;
typedef long double lDouble;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// class FString // class FString
@ -110,15 +113,17 @@ class FString
const char* c_str() const; const char* c_str() const;
const std::string toString() const; const std::string toString() const;
FString toLower() const; FString toLower() const;
FString toUpper() const; FString toUpper() const;
sInt16 toShort() const; sInt16 toShort() const;
uInt16 toUShort() const; uInt16 toUShort() const;
int toInt() const; int toInt() const;
uInt toUInt() const; uInt toUInt() const;
long toLong() const; long toLong() const;
uLong toULong() const; uLong toULong() const;
float toFloat() const;
double toDouble() const;
FString ltrim() const; FString ltrim() const;
FString rtrim() const; FString rtrim() const;
@ -145,6 +150,9 @@ class FString
FString& setNumber (uInt); FString& setNumber (uInt);
FString& setNumber (long); FString& setNumber (long);
FString& setNumber (uLong); FString& setNumber (uLong);
FString& setNumber (float, int precision=8);
FString& setNumber (double, int precision=11);
FString& setNumber (lDouble, int precision=11);
FString& setFormatedNumber (sInt16, char separator='.'); FString& setFormatedNumber (sInt16, char separator='.');
FString& setFormatedNumber (uInt16, char separator='.'); FString& setFormatedNumber (uInt16, char separator='.');
@ -327,6 +335,10 @@ 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)); }
@ -367,6 +379,14 @@ inline FString& FString::setNumber (int num)
inline FString& FString::setNumber (uInt num) inline FString& FString::setNumber (uInt num)
{ return setNumber (uLong(num)); } { return setNumber (uLong(num)); }
//----------------------------------------------------------------------
inline FString& FString::setNumber (float num, int precision)
{ return setNumber (lDouble(num), precision); }
//----------------------------------------------------------------------
inline FString& FString::setNumber (double num, int precision)
{ return setNumber (lDouble(num), precision); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FString& FString::setFormatedNumber (sInt16 num, char separator) inline FString& FString::setFormatedNumber (sInt16 num, char separator)
{ return setFormatedNumber (long(num), separator); } { return setFormatedNumber (long(num), separator); }

View File

@ -14,7 +14,7 @@
#include "fdialog.h" #include "fdialog.h"
#include "fmessagebox.h" #include "fmessagebox.h"
const long double PI = 3.141592653589793238L; const lDouble PI = 3.141592653589793238L;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// class Button // class Button
@ -129,17 +129,17 @@ class Calc : public FDialog
NUM_OF_BUTTONS NUM_OF_BUTTONS
}; };
long double a, b; lDouble a, b;
uInt max_char; uInt max_char;
int last_key; int last_key;
char infix_operator; char infix_operator;
char last_infix_operator; char last_infix_operator;
FString input; FString input;
int button_no[Calc::NUM_OF_BUTTONS]; int button_no[Calc::NUM_OF_BUTTONS];
struct stack_data struct stack_data
{ {
long double term; lDouble term;
char infix_operator; char infix_operator;
}; };
@ -151,7 +151,7 @@ class Calc : public FDialog
virtual void draw(); virtual void draw();
bool isDataEntryKey(int); bool isDataEntryKey(int);
bool isOperatorKey(int); bool isOperatorKey(int);
void setDisplay (long double); void setDisplay (lDouble);
void setInfixOperator(char); void setInfixOperator(char);
void clearInfixOperator(); void clearInfixOperator();
void calcInfixOperator(); void calcInfixOperator();
@ -400,7 +400,7 @@ bool Calc::isOperatorKey(int key)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void Calc::setDisplay (long double d) void Calc::setDisplay (lDouble d)
{ {
char buffer[32]; char buffer[32];
snprintf (buffer, sizeof(buffer), "%31.11Lg", d); snprintf (buffer, sizeof(buffer), "%31.11Lg", d);
@ -535,7 +535,7 @@ void Calc::onClose (FCloseEvent* event)
void Calc::cb_buttonClicked (FWidget*, void* data_ptr) void Calc::cb_buttonClicked (FWidget*, void* data_ptr)
{ {
int key; int key;
long double* x; lDouble* x;
using namespace std; using namespace std;
@ -907,7 +907,7 @@ void Calc::cb_buttonClicked (FWidget*, void* data_ptr)
if ( ! input.isEmpty() ) if ( ! input.isEmpty() )
{ {
if ( isDataEntryKey(key) ) if ( isDataEntryKey(key) )
*x = atof(input.c_str()); *x = input.toDouble();
else else
{ {
// remove trailing zeros // remove trailing zeros

View File

@ -1,5 +1,7 @@
// fstring.cpp // fstring.cpp
#include <iomanip>
#include <langinfo.h> #include <langinfo.h>
#include <term.h> #include <term.h>
#include <unistd.h> #include <unistd.h>
@ -116,21 +118,37 @@ int main (int, char**)
<< formatStr.sprintf("sqrt(%d) = %d", 16, 4) << formatStr.sprintf("sqrt(%d) = %d", 16, 4)
<< std::endl; << std::endl;
FString ulong_str = "123456789"; uLong ulong_num = FString("123456789").toULong();
uLong ulong_num = ulong_str.toULong();
std::cout << " toULong: " << ulong_num << std::endl; std::cout << " toULong: " << ulong_num << std::endl;
FString long_str = "-9876543210"; long long_num = FString("-9876543210").toLong();
long long_num = long_str.toLong();
std::cout << " toLong: " << long_num << std::endl; std::cout << " toLong: " << long_num << std::endl;
FString num1, num2; setlocale(LC_NUMERIC, "C");
try
{
double double_num = FString("2.7182818284590452353").toDouble();
std::cout << " toDouble: " << std::setprecision(11)
<< double_num << std::endl;
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Invalid argument: " << ex.what() << std::endl;
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of range: " << ex.what() << std::endl;
}
FString num1, num2, num3;
num1.setNumber(137); num1.setNumber(137);
num2.setNumber(-512); num2.setNumber(-512);
num3.setNumber(3.141592653589793238L, 12);
std::cout << " setNumber: " std::cout << " setNumber: "
<< num1 << " (unsigned)" << std::endl; << num1 << " (unsigned)" << std::endl;
std::cout << " setNumber: " std::cout << " setNumber: "
<< num2 << " (signed)" << std::endl; << num2 << " (signed)" << std::endl;
std::cout << " setNumber: "
<< num3 << " (long double)" << std::endl;
FString fnum1, fnum2; FString fnum1, fnum2;
fnum1.setFormatedNumber(0xffffffffffffffff, '\''); fnum1.setFormatedNumber(0xffffffffffffffff, '\'');