Class FString: Add toFloat(), toDouble() and setNumber(...) for floating point values
This commit is contained in:
parent
c4fbad06ca
commit
f9001e59de
1
doc/TODO
1
doc/TODO
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -590,7 +590,7 @@ void FButton::onMouseUp (FMouseEvent* event)
|
||||||
setUp();
|
setUp();
|
||||||
if ( getGeometryGlobal().contains(event->getGlobalPos()) )
|
if ( getGeometryGlobal().contains(event->getGlobalPos()) )
|
||||||
processClick();
|
processClick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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); }
|
||||||
|
|
|
@ -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
|
||||||
|
@ -37,7 +37,7 @@ private:
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
Button::Button (FWidget* parent) : FButton(parent)
|
Button::Button (FWidget* parent) : FButton(parent)
|
||||||
{
|
{
|
||||||
checked = false;
|
checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -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();
|
||||||
|
@ -273,7 +273,7 @@ Calc::Calc (FWidget* parent) : FDialog(parent)
|
||||||
calculator_buttons[Change_sign]->addAccelerator('#');
|
calculator_buttons[Change_sign]->addAccelerator('#');
|
||||||
calculator_buttons[Equals]->addAccelerator(fc::Fkey_return);
|
calculator_buttons[Equals]->addAccelerator(fc::Fkey_return);
|
||||||
calculator_buttons[Equals]->addAccelerator(fc::Fkey_enter);
|
calculator_buttons[Equals]->addAccelerator(fc::Fkey_enter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -392,7 +392,7 @@ bool Calc::isOperatorKey(int key)
|
||||||
};
|
};
|
||||||
|
|
||||||
int* iter = std::find (operators, operators+6, key);
|
int* iter = std::find (operators, operators+6, key);
|
||||||
|
|
||||||
if ( iter != operators+6 )
|
if ( iter != operators+6 )
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
|
@ -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);
|
||||||
|
@ -502,7 +502,7 @@ void Calc::onKeyPress (FKeyEvent* event)
|
||||||
}
|
}
|
||||||
event->accept();
|
event->accept();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case fc::Fkey_escape:
|
case fc::Fkey_escape:
|
||||||
case fc::Fkey_escape_mintty:
|
case fc::Fkey_escape_mintty:
|
||||||
FAccelEvent a_ev(Accelerator_Event, getFocusWidget());
|
FAccelEvent a_ev(Accelerator_Event, getFocusWidget());
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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, '\'');
|
||||||
|
|
Loading…
Reference in New Issue