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
|
||||
- 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
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef signed short sInt16;
|
|||
typedef signed int sInt32;
|
||||
typedef int64_t sInt64;
|
||||
|
||||
typedef long double lDouble;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FObject
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "fdialog.h"
|
||||
#include "fmessagebox.h"
|
||||
|
||||
const long double PI = 3.141592653589793238L;
|
||||
const lDouble PI = 3.141592653589793238L;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class Button
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
|
|
@ -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, '\'');
|
||||
|
|
Loading…
Reference in New Issue