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
- long double to FString + FString to long double
- Add a window switcher on the right side of the status bar
- Add a scrolling area with on-demand scroll bars for FButtonGroup

View File

@ -590,7 +590,7 @@ void FButton::onMouseUp (FMouseEvent* event)
setUp();
if ( getGeometryGlobal().contains(event->getGlobalPos()) )
processClick();
}
}
}
//----------------------------------------------------------------------

View File

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

View File

@ -1017,6 +1017,30 @@ uLong FString::toULong() const
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
{
@ -1212,6 +1236,34 @@ FString& FString::setNumber (uLong num)
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)
{

View File

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

View File

@ -14,7 +14,7 @@
#include "fdialog.h"
#include "fmessagebox.h"
const long double PI = 3.141592653589793238L;
const lDouble PI = 3.141592653589793238L;
//----------------------------------------------------------------------
// class Button
@ -37,7 +37,7 @@ private:
//----------------------------------------------------------------------
Button::Button (FWidget* parent) : FButton(parent)
{
checked = false;
checked = false;
}
//----------------------------------------------------------------------
@ -129,17 +129,17 @@ class Calc : public FDialog
NUM_OF_BUTTONS
};
long double a, b;
uInt max_char;
int last_key;
char infix_operator;
char last_infix_operator;
FString input;
int button_no[Calc::NUM_OF_BUTTONS];
lDouble a, b;
uInt max_char;
int last_key;
char infix_operator;
char last_infix_operator;
FString input;
int button_no[Calc::NUM_OF_BUTTONS];
struct stack_data
{
long double term;
lDouble term;
char infix_operator;
};
@ -151,7 +151,7 @@ class Calc : public FDialog
virtual void draw();
bool isDataEntryKey(int);
bool isOperatorKey(int);
void setDisplay (long double);
void setDisplay (lDouble);
void setInfixOperator(char);
void clearInfixOperator();
void calcInfixOperator();
@ -273,7 +273,7 @@ Calc::Calc (FWidget* parent) : FDialog(parent)
calculator_buttons[Change_sign]->addAccelerator('#');
calculator_buttons[Equals]->addAccelerator(fc::Fkey_return);
calculator_buttons[Equals]->addAccelerator(fc::Fkey_enter);
}
//----------------------------------------------------------------------
@ -392,7 +392,7 @@ bool Calc::isOperatorKey(int key)
};
int* iter = std::find (operators, operators+6, key);
if ( iter != operators+6 )
return true;
else
@ -400,7 +400,7 @@ bool Calc::isOperatorKey(int key)
}
//----------------------------------------------------------------------
void Calc::setDisplay (long double d)
void Calc::setDisplay (lDouble d)
{
char buffer[32];
snprintf (buffer, sizeof(buffer), "%31.11Lg", d);
@ -502,7 +502,7 @@ void Calc::onKeyPress (FKeyEvent* event)
}
event->accept();
break;
case fc::Fkey_escape:
case fc::Fkey_escape_mintty:
FAccelEvent a_ev(Accelerator_Event, getFocusWidget());
@ -535,7 +535,7 @@ void Calc::onClose (FCloseEvent* event)
void Calc::cb_buttonClicked (FWidget*, void* data_ptr)
{
int key;
long double* x;
lDouble* x;
using namespace std;
@ -907,7 +907,7 @@ void Calc::cb_buttonClicked (FWidget*, void* data_ptr)
if ( ! input.isEmpty() )
{
if ( isDataEntryKey(key) )
*x = atof(input.c_str());
*x = input.toDouble();
else
{
// remove trailing zeros

View File

@ -1,5 +1,7 @@
// fstring.cpp
#include <iomanip>
#include <langinfo.h>
#include <term.h>
#include <unistd.h>
@ -116,21 +118,37 @@ int main (int, char**)
<< formatStr.sprintf("sqrt(%d) = %d", 16, 4)
<< std::endl;
FString ulong_str = "123456789";
uLong ulong_num = ulong_str.toULong();
uLong ulong_num = FString("123456789").toULong();
std::cout << " toULong: " << ulong_num << std::endl;
FString long_str = "-9876543210";
long long_num = long_str.toLong();
long long_num = FString("-9876543210").toLong();
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);
num2.setNumber(-512);
num3.setNumber(3.141592653589793238L, 12);
std::cout << " setNumber: "
<< num1 << " (unsigned)" << std::endl;
<< num1 << " (unsigned)" << std::endl;
std::cout << " setNumber: "
<< num2 << " (signed)" << std::endl;
<< num2 << " (signed)" << std::endl;
std::cout << " setNumber: "
<< num3 << " (long double)" << std::endl;
FString fnum1, fnum2;
fnum1.setFormatedNumber(0xffffffffffffffff, '\'');