service plugin and qdecimal library has been added
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
/** \file DeciContext.cc
|
||||
* Definitions for the class QDecContext.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "QDecContext.hh"
|
||||
//include <sstream>
|
||||
#include <QtGlobal>
|
||||
#include <QByteArray>
|
||||
#include <QTextStream>
|
||||
#include "QDecFwd.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
QDecContext::QDecContext(int32_t kind)
|
||||
{
|
||||
switch(kind) {
|
||||
case DEC_INIT_BASE:
|
||||
case DEC_INIT_DECIMAL32:
|
||||
case DEC_INIT_DECIMAL64:
|
||||
case DEC_INIT_DECIMAL128:
|
||||
// Above kinds must be specified
|
||||
break;
|
||||
|
||||
default:
|
||||
// Invalid kind
|
||||
throw("Invalid QDecContext kind");
|
||||
}
|
||||
|
||||
decContextDefault(&m_data, kind);
|
||||
|
||||
// No SIGFPE trap is allowed by default
|
||||
// as this will disrupt most calculations.
|
||||
m_data.traps = 0;
|
||||
|
||||
// By default allow maximum allowable precision
|
||||
setDigits(QDecNumDigits);
|
||||
}
|
||||
|
||||
|
||||
QByteArray QDecContext::statusFlags() const
|
||||
{
|
||||
uint32_t status = m_data.status;
|
||||
QByteArray str;
|
||||
QTextStream os(&str);
|
||||
//ostringstream os;
|
||||
const char sep = '|'; // Separator
|
||||
|
||||
if(status & DEC_Conversion_syntax)
|
||||
os << DEC_Condition_CS << sep;
|
||||
if(status & DEC_Division_by_zero)
|
||||
os << DEC_Condition_DZ << sep;
|
||||
if(status & DEC_Division_impossible)
|
||||
os << DEC_Condition_DI << sep;
|
||||
if(status & DEC_Division_undefined)
|
||||
os << DEC_Condition_DU << sep;
|
||||
if(status & DEC_Inexact)
|
||||
os << DEC_Condition_IE << sep;
|
||||
if(status & DEC_Invalid_context)
|
||||
os << DEC_Condition_IC << sep;
|
||||
if(status & DEC_Insufficient_storage)
|
||||
os << DEC_Condition_IS << sep;
|
||||
if(status & DEC_Invalid_operation)
|
||||
os << DEC_Condition_IO << sep;
|
||||
#if DECSUBSET
|
||||
if(status & DEC_Lost_digits)
|
||||
os << DEC_Condition_LD << sep;
|
||||
#endif
|
||||
if(status & DEC_Overflow)
|
||||
os << DEC_Condition_OV << sep;
|
||||
if(status & DEC_Clamped)
|
||||
os << DEC_Condition_PA << sep;
|
||||
if(status & DEC_Rounded)
|
||||
os << DEC_Condition_RO << sep;
|
||||
if(status & DEC_Subnormal)
|
||||
os << DEC_Condition_SU << sep;
|
||||
if(status & DEC_Underflow)
|
||||
os << DEC_Condition_UN << sep;
|
||||
if(0==status)
|
||||
os << DEC_Condition_ZE << sep;
|
||||
|
||||
os << "0x" << hex << status;
|
||||
|
||||
os.flush();
|
||||
//return os.str().c_str();
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
uint8_t QDecContext::extended() const
|
||||
{
|
||||
#if DECSUBSET
|
||||
return m_data.extended;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void QDecContext::setExtended(uint8_t ext)
|
||||
{
|
||||
#if DECSUBSET
|
||||
m_data.extended = ext;
|
||||
#else
|
||||
(void)ext; // To disable compiler warning
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecContext ctx)
|
||||
{
|
||||
char c = ' ';
|
||||
ts << "digits=" << ctx.digits()
|
||||
<< c << "emax=" << ctx.emax()
|
||||
<< c << "emin=" << ctx.emin()
|
||||
<< c << "extended=" << ctx.extended()
|
||||
<< c << "clamp=" << ctx.clamp()
|
||||
<< c << "round=" << ctx.round()
|
||||
<< c << "traps=" << ctx.traps()
|
||||
<< c << "status=" << ctx.status()
|
||||
<< c << ctx.statusToString();
|
||||
|
||||
return ts;
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
#ifndef QDECCONTEXT_HH
|
||||
#define QDECCONTEXT_HH
|
||||
|
||||
/** \file QDecContext.hh
|
||||
* Declarations for the class QDecContext.
|
||||
*
|
||||
* (C) Copyright Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "decContext.h"
|
||||
}
|
||||
#include "QDecFwd.hh"
|
||||
|
||||
|
||||
// FORWARDS
|
||||
class QByteArray;
|
||||
class QTextStream;
|
||||
|
||||
/*! Default context type or kind, should be set to one of these:
|
||||
* DEC_INIT_BASE
|
||||
* DEC_INIT_DECIMAL32
|
||||
* DEC_INIT_DECIMAL64
|
||||
* DEC_INIT_DECIMAL128
|
||||
*/
|
||||
const int QDecContextDefKind = DEC_INIT_BASE;
|
||||
|
||||
|
||||
//! Maximum precision allowed in precision (digits) field
|
||||
const int32_t QDecMaxPrecision = 999999999;
|
||||
const int32_t QDecMaxExponent = 999999999;
|
||||
const int32_t QDecMinExponent = -999999999;
|
||||
|
||||
/*!
|
||||
\class QDecContext
|
||||
QDecContext encapsulates decContext structure as member and
|
||||
exposes free-standing functions as member functions.
|
||||
Most functions in the decNumber module take as an argument a
|
||||
decContext structure, which provides the context for operations
|
||||
(precision, rounding mode, etc.) and also controls the handling of
|
||||
exceptional conditions (corresponding to the flags and trap enablers
|
||||
in a hardware floating-point implementation).
|
||||
*/
|
||||
class QDECIMAL_EXPORT QDecContext
|
||||
{
|
||||
// MEMBERS
|
||||
//! Embedded decContext structure
|
||||
decContext m_data;
|
||||
|
||||
public:
|
||||
// TYPES
|
||||
typedef decContext* decContextPtr_t;
|
||||
typedef enum rounding Rounding_e;
|
||||
|
||||
// CREATORS
|
||||
//! Default constructor
|
||||
QDecContext(int32_t kind = QDecContextDefKind);
|
||||
QDecContext(const decContext* cptr) : m_data(*cptr) {}
|
||||
QDecContext(const decContext& data) : m_data(data) {}
|
||||
// Default Copy Ctor and Dtor and Copy assignment are ok
|
||||
|
||||
|
||||
// ACCESSORS
|
||||
//! Get decContext member
|
||||
const decContext* data() const
|
||||
{ return &m_data; }
|
||||
|
||||
//! Get clamp flag of the context (IEEE exponent clamp)
|
||||
uint8_t clamp() const
|
||||
{ return m_data.clamp; }
|
||||
|
||||
//! Get digits field of the context (working precision)
|
||||
int32_t digits() const
|
||||
{ return m_data.digits; }
|
||||
|
||||
//! Get emax field of the context (maximum positive exponent)
|
||||
int32_t emax() const
|
||||
{ return m_data.emax; }
|
||||
|
||||
//! Get emin field of the context (minimum negative exponent)
|
||||
int32_t emin() const
|
||||
{ return m_data.emin; }
|
||||
|
||||
//! Get extended flag of the context (special values)
|
||||
uint8_t extended() const;
|
||||
|
||||
//! Get round field of the context (rounding mode)
|
||||
Rounding_e round() const
|
||||
{ return m_data.round; }
|
||||
|
||||
//! Get status flags of the context
|
||||
uint32_t status() const
|
||||
{ return m_data.status; }
|
||||
|
||||
//! Get trap-enabler flags of the context
|
||||
uint32_t traps() const
|
||||
{ return m_data.traps; }
|
||||
|
||||
|
||||
// MODIFIERS
|
||||
//! Get decContext member
|
||||
decContext* data()
|
||||
{ return &m_data; }
|
||||
|
||||
//! Set clamp flag of the context (IEEE exponent clamp)
|
||||
void setClamp(uint32_t clamp)
|
||||
{ m_data.clamp = clamp; }
|
||||
|
||||
//! Set digits field of the context (working precision)
|
||||
void setDigits(int32_t digits)
|
||||
{ m_data.digits = digits; }
|
||||
|
||||
//! Set emax field of the context (maximum positive exponent)
|
||||
void setEmax(int32_t emax)
|
||||
{ m_data.emax = emax; }
|
||||
|
||||
//! Set emin field of the context (minimum negative exponent)
|
||||
void setEmin(int32_t emin)
|
||||
{ m_data.emin = emin; }
|
||||
|
||||
//! Set extended flag of the context (special values)
|
||||
void setExtended(uint8_t ext);
|
||||
|
||||
//! This function is used to return the round (rounding mode) field
|
||||
//! of a decContext.
|
||||
void setRound(Rounding_e round)
|
||||
{ m_data.round = round; }
|
||||
|
||||
void setTraps(uint32_t traps)
|
||||
{ m_data.traps = traps; }
|
||||
|
||||
/*!
|
||||
This function is used to set one or more status bits in the status
|
||||
field of a decContext. If any of the bits being set have the
|
||||
corresponding bit set in the traps field, a trap is raised
|
||||
(regardless of whether the bit is already set in the status field).
|
||||
Only one trap is raised even if more than one bit is being set.
|
||||
*/
|
||||
void setStatus(uint32_t status = 0)
|
||||
{ m_data.status = status; }
|
||||
|
||||
//! This function is identical to setStatus except that
|
||||
//! the context traps field is ignored (i.e., no trap is raised).
|
||||
void setStatusQuiet(uint32_t status = 0)
|
||||
{ decContextSetStatusQuiet(&m_data, status); }
|
||||
|
||||
// ROUTINES
|
||||
//! This function is used to clear (set to zero) one or more status
|
||||
//! bits in the status field of a decContext.
|
||||
QDecContext& clearStatus(uint32_t status)
|
||||
{ decContextClearStatus(&m_data, status); return *this; }
|
||||
|
||||
//! This function is used to restore one or more status bits in
|
||||
//! the status field of a decContext from a saved status field.
|
||||
QDecContext& restoreStatus(uint32_t status, uint32_t mask)
|
||||
{ decContextRestoreStatus(&m_data, status, mask); return *this; }
|
||||
|
||||
/*!
|
||||
This function is used to initialize a decContext structure to
|
||||
default values. It is stongly recommended that this function always
|
||||
be used to initialize a decContext structure, even if most or all
|
||||
of the fields are to be set explicitly (in case new fields are added
|
||||
to a later version of the structure).
|
||||
*/
|
||||
QDecContext& setDefault(int32_t kind = QDecContextDefKind)
|
||||
{ decContextDefault(&m_data, kind); return *this; }
|
||||
|
||||
//! This function is used to save one or more status bits from
|
||||
//! the status field of a decContext.
|
||||
uint32_t saveStatus(uint32_t mask)
|
||||
{ return decContextSaveStatus(&m_data, mask); }
|
||||
|
||||
/*!
|
||||
This function is used to set a status bit in the status field of a
|
||||
decContext, using the name of the bit as returned by the
|
||||
decContextStatusToString function. If the bit being set has the
|
||||
corresponding bit set in the traps field, a trap is raised
|
||||
(regardless of whether the bit is already set in the status field).
|
||||
*/
|
||||
QDecContext& setStatusFromString(const char* str)
|
||||
{ decContextSetStatusFromString(&m_data, str); return *this; }
|
||||
|
||||
//! This function is identical to setStatusFromString except
|
||||
//! that the context traps field is ignored (i.e., no trap is raised).
|
||||
QDecContext& setStatusFromStringQuiet(const char* str)
|
||||
{ decContextSetStatusFromStringQuiet(&m_data, str); return *this; }
|
||||
|
||||
//! This function returns a pointer (char *) to a human-readable
|
||||
//! description of a status bit. The string pointed to will be a constant.
|
||||
const char* statusToString() const
|
||||
{ return decContextStatusToString(&m_data); }
|
||||
|
||||
//! This function is used to test one or more status bits in a context.
|
||||
uint32_t testStatus(uint32_t mask) //const
|
||||
{ return decContextTestStatus(&m_data, mask); }
|
||||
|
||||
//! This function is used to clear (set to zero) all the
|
||||
//! status bits in the status field of a decContext.
|
||||
QDecContext& zeroStatus()
|
||||
{ decContextZeroStatus(&m_data); return *this; }
|
||||
|
||||
|
||||
// UTILITY ROUTINES
|
||||
//! Get status flags (fields) in string form
|
||||
//! separated by | character
|
||||
QByteArray statusFlags() const;
|
||||
|
||||
//! Throw exception if status flags are set.
|
||||
void throwOnError() const
|
||||
{ if(m_data.status) throw(statusToString()); }
|
||||
|
||||
//! Type conversion operator to decContext*
|
||||
operator decContextPtr_t() { return &m_data; }
|
||||
|
||||
|
||||
// STATIC FUNCTIONS
|
||||
//! This function checks that the DECLITEND tuning
|
||||
//! parameter is set correctly.
|
||||
//! Returns 0 if the DECLITEND parameter is correct,
|
||||
//! 1 if it is incorrect and should be set to 1, and
|
||||
//! -1 if it is incorrect and should be set to 0.
|
||||
static int TestEndian()
|
||||
{ return decContextTestEndian(1 /*Quiet*/); }
|
||||
|
||||
//! This function is used to test one or more status
|
||||
//! bits in a saved status field.
|
||||
static uint32_t TestSavedStatus(uint32_t status, uint32_t mask)
|
||||
{ return decContextTestSavedStatus(status, mask); }
|
||||
|
||||
|
||||
}; // end class
|
||||
|
||||
|
||||
/*!
|
||||
QTextStream inserter to pretty-print QDecContext objects
|
||||
in the debug stream.
|
||||
*/
|
||||
QDECIMAL_EXPORT
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecContext);
|
||||
|
||||
|
||||
//! Convience macro to extract decContext structure or
|
||||
//! create one on stack to comply with callee signature.
|
||||
#define CXT(cptr) ( cptr ? cptr->data() : QDecContext().data() )
|
||||
|
||||
#endif /* Include guard */
|
||||
@@ -0,0 +1,116 @@
|
||||
/** \file QDecDouble.cc
|
||||
* Definitions for the class QDecDouble.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "QDecDouble.hh"
|
||||
extern "C" {
|
||||
#include "decimal64.h"
|
||||
}
|
||||
#include <stdlib.h>
|
||||
#include <QTextStream>
|
||||
#include "QDecNumber.hh"
|
||||
#include "QDecPacked.hh"
|
||||
#include "QDecSingle.hh"
|
||||
#include "QDecQuad.hh"
|
||||
|
||||
|
||||
QDecDouble& QDecDouble::fromDouble(double d)
|
||||
{
|
||||
char str[MaxStrSize] = { 0 };
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
_snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d);
|
||||
#else
|
||||
snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d);
|
||||
#endif
|
||||
|
||||
return fromString(str);
|
||||
}
|
||||
|
||||
QDecDouble& QDecDouble::fromHexString(const char* str)
|
||||
{
|
||||
QByteArray ba = QByteArray::fromHex(str);
|
||||
int size = sizeof(m_data);
|
||||
char* p = (char*)&m_data;
|
||||
int i = 0;
|
||||
int j = size-1;
|
||||
for(; i<size; i++,j--)
|
||||
p[j] = ba.at(i);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecDouble& QDecDouble::fromQDecSingle(const QDecSingle& s)
|
||||
{
|
||||
decSingleToWider(s.data(), &m_data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecDouble& QDecDouble::fromQDecNumber(const QDecNumber& n, QDecContext* c)
|
||||
{
|
||||
decDoubleFromNumber(&m_data, n.data(), CXT(c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecDouble& QDecDouble::fromQDecPacked(const QDecPacked& p)
|
||||
{
|
||||
fromQDecNumber(p.toQDecNumber());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecDouble& QDecDouble::fromWider(const QDecQuad& q, QDecContext* c)
|
||||
{
|
||||
decDoubleFromWider(&m_data, q.data(), CXT(c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
double QDecDouble::toDouble() const
|
||||
{
|
||||
char str[MaxStrSize] = { 0 };
|
||||
decDoubleToString(&m_data, str);
|
||||
return strtod(str, 0);
|
||||
}
|
||||
|
||||
QDecSingle QDecDouble::toQDecSingle(QDecContext* c) const
|
||||
{
|
||||
decSingle s;
|
||||
return decSingleFromWider(&s, &m_data, CXT(c));
|
||||
}
|
||||
|
||||
QDecQuad QDecDouble::toQDecQuad() const
|
||||
{
|
||||
decQuad q;
|
||||
return decDoubleToWider(&m_data, &q);
|
||||
}
|
||||
|
||||
QDecPacked QDecDouble::toQDecPacked() const
|
||||
{
|
||||
return QDecPacked(toQDecNumber());
|
||||
}
|
||||
|
||||
QDecNumber QDecDouble::toQDecNumber() const
|
||||
{
|
||||
decNumber n;
|
||||
return decDoubleToNumber(&m_data, &n);
|
||||
}
|
||||
|
||||
QDecQuad QDecDouble::toWider() const
|
||||
{
|
||||
decQuad q;
|
||||
return decDoubleToWider(&m_data, &q);
|
||||
}
|
||||
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecDouble& d)
|
||||
{
|
||||
ts << d.toString();
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,454 @@
|
||||
#ifndef QDECDOUBLE_HH
|
||||
#define QDECDOUBLE_HH
|
||||
|
||||
/** \file QDecDouble.hh
|
||||
* Declarations for the class QDecDouble.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "QDecFwd.hh"
|
||||
#include "QDecContext.hh"
|
||||
extern "C" {
|
||||
#include "decDouble.h"
|
||||
}
|
||||
|
||||
// FORWARDS
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTextStream;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
/*!
|
||||
\class QDecDouble
|
||||
QDecDouble encapsulates decDouble and provides decNumber library
|
||||
functions that operates upon decSingle as member functions with the same name.
|
||||
decimal64 is a 64-bit decimal floating-point representation which
|
||||
provides 16 decimal digits of precision in a compressed format.
|
||||
decDouble module provides the functions for the decimal64 format;
|
||||
this format is an IEEE 754 basic format and so a full set of arithmetic
|
||||
and other functions is included.
|
||||
*/
|
||||
class QDECIMAL_EXPORT QDecDouble
|
||||
{
|
||||
// MEMBERS
|
||||
//! Embedded decDouble structure
|
||||
decDouble m_data;
|
||||
|
||||
public:
|
||||
// TYPES
|
||||
typedef decDouble* decDoublePtr_t;
|
||||
enum {
|
||||
MaxStrSize = QDECMAXSTRSIZE
|
||||
};
|
||||
|
||||
|
||||
// CREATORS
|
||||
//! Default constructor
|
||||
QDecDouble() { decDoubleZero(&m_data); }
|
||||
|
||||
// Default Dtor and Copy Ctor are ok
|
||||
|
||||
// Constructors using decDouble structure
|
||||
QDecDouble(decDouble d) : m_data(d) {}
|
||||
QDecDouble(const decDouble* p) : m_data(*p) {}
|
||||
|
||||
// Conversion constructors using simple types
|
||||
QDecDouble(const char* str) { fromString(str); }
|
||||
QDecDouble(int32_t i) { fromInt32(i); }
|
||||
QDecDouble(uint32_t i) { fromUInt32(i); }
|
||||
QDecDouble(double d) { fromDouble(d); }
|
||||
|
||||
|
||||
// Conversion constructors using composite types
|
||||
QDecDouble(const QDecQuad& q) { fromQDecQuad(q); }
|
||||
QDecDouble(const QDecSingle& s) { fromQDecSingle(s); }
|
||||
QDecDouble(const QDecPacked& p) { fromQDecPacked(p); }
|
||||
QDecDouble(const QDecNumber& n) { fromQDecNumber(n); }
|
||||
|
||||
|
||||
//! Copy assignment
|
||||
QDecDouble& operator=(const QDecDouble& o)
|
||||
{ return (this != &o ? copy(o) : *this); }
|
||||
|
||||
//! Conversion operator to decDouble*
|
||||
operator decDoublePtr_t() { return &m_data; }
|
||||
|
||||
|
||||
// ACCESSORS
|
||||
const decDouble* data() const
|
||||
{ return &m_data; }
|
||||
|
||||
// MODIFIERS
|
||||
decDouble* data()
|
||||
{ return &m_data; }
|
||||
|
||||
// UTILITIES & CONVERSIONS
|
||||
QDecDouble& fromBCD(int32_t exp, const QByteArray& bcd, int32_t sign) {
|
||||
decDoubleFromBCD(&m_data, exp, (const uint8_t*)bcd.data(), sign);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecDouble& fromDouble(double d);
|
||||
|
||||
QDecDouble& fromInt32(int32_t i)
|
||||
{ decDoubleFromInt32(&m_data, i); return *this; }
|
||||
|
||||
QDecDouble& fromPacked(int32_t exp, const QByteArray& pack) {
|
||||
decDoubleFromPacked(&m_data, exp, (const uint8_t*)pack.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecDouble& fromPackedChecked(int32_t exp, const QByteArray& pack) {
|
||||
decDoubleFromPackedChecked(&m_data, exp, (const uint8_t*)pack.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecDouble& fromString(const char* str, QDecContext* c = 0)
|
||||
{ decDoubleFromString(&m_data, str, CXT(c)); return *this; }
|
||||
|
||||
//! Hexadecimal string in network byte order
|
||||
QDecDouble& fromHexString(const char* str);
|
||||
|
||||
QDecDouble& fromQDecSingle(const QDecSingle& s);
|
||||
|
||||
QDecDouble& fromQDecQuad(const QDecQuad& q, QDecContext* c = 0)
|
||||
{ return fromWider(q, c); }
|
||||
|
||||
QDecDouble& fromQDecNumber(const QDecNumber& n, QDecContext* c = 0);
|
||||
|
||||
QDecDouble& fromQDecPacked(const QDecPacked& p);
|
||||
|
||||
QDecDouble& fromUInt32(uint32_t i)
|
||||
{ decDoubleFromUInt32(&m_data, i); return *this; }
|
||||
|
||||
QDecDouble& fromWider(const QDecQuad& q, QDecContext* c = 0);
|
||||
|
||||
int32_t getCoefficient(QByteArray& bcd) const {
|
||||
bcd.resize(DECDOUBLE_Pmax);
|
||||
return decDoubleGetCoefficient(&m_data, (uint8_t*)bcd.data());
|
||||
}
|
||||
|
||||
QDecDouble& setCoefficient(const QByteArray& bcd, int32_t sign) {
|
||||
decDoubleSetCoefficient(&m_data, (const uint8_t*)bcd.data(), sign);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecDouble& setExponent(int32_t exp, QDecContext* c = 0 ) {
|
||||
decDoubleSetExponent(&m_data, CXT(c), exp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int32_t toBCD(int32_t& exp, QByteArray& bcd) {
|
||||
bcd.resize(DECDOUBLE_Pmax);
|
||||
return decDoubleToBCD(&m_data, &exp, (uint8_t*)bcd.data());
|
||||
}
|
||||
|
||||
double toDouble() const;
|
||||
|
||||
QByteArray toEngString() const {
|
||||
char str[MaxStrSize] = { 0 };
|
||||
return decDoubleToEngString(&m_data, str);
|
||||
}
|
||||
|
||||
int32_t toPacked(int32_t& exp, QByteArray& pack) {
|
||||
pack.resize(DECDOUBLE_Pmax);
|
||||
return decDoubleToPacked(&m_data, &exp, (uint8_t*)pack.data());
|
||||
}
|
||||
|
||||
QByteArray toString() const {
|
||||
char str[MaxStrSize] = { 0 };
|
||||
return decDoubleToString(&m_data, str);
|
||||
}
|
||||
|
||||
QDecSingle toQDecSingle(QDecContext* c = 0) const;
|
||||
|
||||
QDecQuad toQDecQuad() const;
|
||||
|
||||
QDecPacked toQDecPacked() const;
|
||||
|
||||
QDecNumber toQDecNumber() const;
|
||||
|
||||
QDecQuad toWider() const;
|
||||
|
||||
QDecDouble& zero()
|
||||
{ decDoubleZero(&m_data); return *this; }
|
||||
|
||||
|
||||
// COMPUTATIONAL
|
||||
//! Returns the absolute value
|
||||
QDecDouble abs(QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleAbs(&d, &m_data, CXT(c)); }
|
||||
|
||||
QDecDouble add(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleAdd(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble digitAnd(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleAnd(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble divide(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleDivide(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble divideInteger(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleDivideInteger(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble fma(const QDecDouble& o, const QDecDouble& o2,
|
||||
QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleFMA(&d, &m_data, &o.m_data, &o2.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble invert(QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleInvert(&d, &m_data, CXT(c)); }
|
||||
|
||||
QDecDouble logB(QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleLogB(&d, &m_data, CXT(c)); }
|
||||
|
||||
QDecDouble max(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleMax(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble maxMag(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleMaxMag(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble minus(QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleMinus(&d, &m_data, CXT(c)); }
|
||||
|
||||
QDecDouble multiply(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleMultiply(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble nextMinus(QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleNextMinus(&d, &m_data, CXT(c)); }
|
||||
|
||||
QDecDouble nextPlus(QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleNextPlus(&d, &m_data, CXT(c)); }
|
||||
|
||||
QDecDouble nextToward(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleNextToward(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble digitOr(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleOr(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble plus(QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoublePlus(&d, &m_data, CXT(c)); }
|
||||
|
||||
QDecDouble quantize(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleQuantize(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble reduce(QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleReduce(&d, &m_data, CXT(c)); }
|
||||
|
||||
QDecDouble remainder(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleRemainder(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble remainderNear(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleRemainderNear(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble rotate(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleRotate(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble scaleB(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleScaleB(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble shift(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleShift(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble subtract(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleSubtract(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble toIntegralValue(enum rounding r, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleToIntegralValue(&d, &m_data, CXT(c), r); }
|
||||
|
||||
QDecDouble toIntegralExact(QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleToIntegralExact(&d, &m_data, CXT(c)); }
|
||||
|
||||
QDecDouble digitXor(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleXor(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
|
||||
// COMPARISONS
|
||||
QDecDouble compare(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleCompare(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble compareSignal(const QDecDouble& o, QDecContext* c = 0) const
|
||||
{ decDouble d; return decDoubleCompareSignal(&d, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecDouble compareTotal(const QDecDouble& o) const
|
||||
{ decDouble d; return decDoubleCompareTotal(&d, &m_data, &o.m_data); }
|
||||
|
||||
QDecDouble compareTotalMag(const QDecDouble& o) const
|
||||
{ decDouble d; return decDoubleCompareTotalMag(&d, &m_data, &o.m_data); }
|
||||
|
||||
|
||||
// COPIES
|
||||
QDecDouble& canonical(const QDecDouble& d)
|
||||
{ decDoubleCanonical(&m_data, &d.m_data); return *this; }
|
||||
|
||||
QDecDouble& copy(const QDecDouble& d)
|
||||
{ decDoubleCopy(&m_data, &d.m_data); return *this; }
|
||||
|
||||
QDecDouble& copyAbs(const QDecDouble& d)
|
||||
{ decDoubleCopyAbs(&m_data, &d.m_data); return *this; }
|
||||
|
||||
QDecDouble& copyNegate(const QDecDouble& d)
|
||||
{ decDoubleCopyNegate(&m_data, &d.m_data); return *this; }
|
||||
|
||||
QDecDouble& copySign(const QDecDouble& d, const QDecDouble& sd)
|
||||
{ decDoubleCopySign(&m_data, &d.m_data, &sd.m_data); return *this; }
|
||||
|
||||
|
||||
// NON-COMPUTATIONAL
|
||||
// "class" is a reserved word in C++
|
||||
enum decClass classification() const
|
||||
{ return decDoubleClass(&m_data); }
|
||||
|
||||
const char* classString() const
|
||||
{ return decDoubleClassString(&m_data); }
|
||||
|
||||
uint32_t digits() const
|
||||
{ return decDoubleDigits(&m_data); }
|
||||
|
||||
bool isCanonical() const
|
||||
{ return decDoubleIsCanonical(&m_data); }
|
||||
|
||||
bool isFinite() const
|
||||
{ return decDoubleIsFinite(&m_data); }
|
||||
|
||||
bool isInteger() const
|
||||
{ return decDoubleIsInteger(&m_data); }
|
||||
|
||||
bool isLogical() const
|
||||
{ return decDoubleIsLogical(&m_data); }
|
||||
|
||||
bool isInfinite() const
|
||||
{ return decDoubleIsInfinite(&m_data); }
|
||||
|
||||
bool isNaN() const
|
||||
{ return decDoubleIsNaN(&m_data); }
|
||||
|
||||
bool isNegative() const
|
||||
{ return decDoubleIsNegative(&m_data); }
|
||||
|
||||
bool isNormal() const
|
||||
{ return decDoubleIsNormal(&m_data); }
|
||||
|
||||
bool isPositive() const
|
||||
{ return decDoubleIsPositive(&m_data); }
|
||||
|
||||
bool isSignaling() const
|
||||
{ return decDoubleIsSignaling(&m_data); }
|
||||
|
||||
bool isSignalling() const
|
||||
{ return decDoubleIsSignalling(&m_data); }
|
||||
|
||||
bool isSigned() const
|
||||
{ return decDoubleIsSigned(&m_data); }
|
||||
|
||||
bool isSubnormal() const
|
||||
{ return decDoubleIsSubnormal(&m_data); }
|
||||
|
||||
bool isZero() const
|
||||
{ return decDoubleIsZero(&m_data); }
|
||||
|
||||
uint32_t radix() const
|
||||
{ return decDoubleRadix(&m_data); }
|
||||
|
||||
const char* version() const
|
||||
{ return decDoubleVersion(); }
|
||||
|
||||
|
||||
// RELATIONAL AND LOGICAL OPERATORS
|
||||
bool operator==(const QDecDouble& o) const
|
||||
{ return compare(o).isZero(); }
|
||||
|
||||
bool operator!=(const QDecDouble& o) const
|
||||
{ return !(this->operator==(o)); }
|
||||
|
||||
bool operator<(const QDecDouble& o) const
|
||||
{ return compare(o).isNegative(); }
|
||||
|
||||
bool operator<=(const QDecDouble& o) const
|
||||
{
|
||||
const QDecDouble& r = compare(o);
|
||||
return r.isNegative() || r.isZero();
|
||||
}
|
||||
|
||||
bool operator>(const QDecDouble& o) const
|
||||
{ return !(this->operator<=(o)); }
|
||||
|
||||
bool operator>=(const QDecDouble& o) const
|
||||
{
|
||||
const QDecDouble& r = compare(o);
|
||||
return !r.isNegative() || r.isZero();
|
||||
}
|
||||
|
||||
// BITWISE OPERATORS
|
||||
QDecDouble operator&(const QDecDouble& o) const
|
||||
{ return digitAnd(o); }
|
||||
|
||||
QDecDouble operator|(const QDecDouble& o) const
|
||||
{ return digitOr(o); }
|
||||
|
||||
QDecDouble operator^(const QDecDouble& o) const
|
||||
{ return digitXor(o); }
|
||||
|
||||
|
||||
// ARITHMETIC OPERATORS
|
||||
QDecDouble operator+(const QDecDouble& o) const
|
||||
{ return add(o); }
|
||||
|
||||
QDecDouble operator-(const QDecDouble& o) const
|
||||
{ return subtract(o); }
|
||||
|
||||
QDecDouble operator*(const QDecDouble& o) const
|
||||
{ return multiply(o); }
|
||||
|
||||
QDecDouble operator/(const QDecDouble& o) const
|
||||
{ return divide(o); }
|
||||
|
||||
QDecDouble operator%(const QDecDouble& o) const
|
||||
{ return remainder(o); }
|
||||
|
||||
|
||||
// COMPOUND ASSIGNMENT OPERATORS
|
||||
QDecDouble& operator+=(const QDecDouble& o)
|
||||
{ return copy(add(o)); }
|
||||
|
||||
QDecDouble& operator-=(const QDecDouble& o)
|
||||
{ return copy(subtract(o)); }
|
||||
|
||||
QDecDouble& operator*=(const QDecDouble& o)
|
||||
{ return copy(multiply(o)); }
|
||||
|
||||
QDecDouble& operator/=(const QDecDouble& o)
|
||||
{ return copy(divide(o)); }
|
||||
|
||||
QDecDouble& operator%=(const QDecDouble& o)
|
||||
{ return copy(remainder(o)); }
|
||||
|
||||
QDecDouble& operator&=(const QDecDouble& o)
|
||||
{ return copy(digitAnd(o)); }
|
||||
|
||||
QDecDouble& operator|=(const QDecDouble& o)
|
||||
{ return copy(digitOr(o)); }
|
||||
|
||||
QDecDouble& operator^=(const QDecDouble& o)
|
||||
{ return copy(digitXor(o)); }
|
||||
|
||||
|
||||
}; // end class
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(QDecDouble);
|
||||
|
||||
|
||||
QDECIMAL_EXPORT
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecDouble& d);
|
||||
|
||||
|
||||
#endif /* Include guard */
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef QDECFWD_HH
|
||||
#define QDECFWD_HH
|
||||
|
||||
/** \file QDecFwd.hh
|
||||
* Forward declarations for QDecimal types
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#ifndef DECNUMDIGITS
|
||||
//! Work with up to 80 digits as default, resulting in 64 bytes
|
||||
//! decNumber structure.
|
||||
# define DECNUMDIGITS 80
|
||||
#endif
|
||||
|
||||
//! Digits of decimal precision for QDecNumber, decNumber.
|
||||
//! This is set at compile time via DECNUMDIGITS macro.
|
||||
const int QDecNumDigits = DECNUMDIGITS;
|
||||
|
||||
//! Digits of decimal precision for QDecSingle, decSingle, decimal32
|
||||
const int QDecSingleDigits = 7;
|
||||
|
||||
//! Digits of decimal precision for QDecDouble, decDouble, decimal64
|
||||
const int QDecDoubleDigits = 16;
|
||||
|
||||
//! Digits of decimal precision for QDecQuad, decQuad, decimal128
|
||||
const int QDecQuadDigits = 34;
|
||||
|
||||
#ifndef QDECMAXSTRSIZE
|
||||
//! Maximum length of a conversion string
|
||||
# define QDECMAXSTRSIZE 512
|
||||
#endif
|
||||
|
||||
|
||||
extern "C" {
|
||||
#if !defined(int32_t)
|
||||
#if defined(_MSC_VER)
|
||||
/* MS Visual C */
|
||||
#include <VCpp_stdint.h>
|
||||
#else
|
||||
/* C99 standard integers */
|
||||
#include <stdint.h>
|
||||
/* For unknown compilers, you can use portable stdint.h */
|
||||
//include <Port_stdint.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "decContext.h"
|
||||
#include "decNumber.h"
|
||||
}
|
||||
|
||||
// Prepare for shared library usage.
|
||||
// See Q_DEC_EXPORT from Qt documentation for details.
|
||||
|
||||
#ifdef QDECIMAL_SHARED
|
||||
# if(QDECIMAL_SHARED > 1)
|
||||
# define QDECIMAL_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QDECIMAL_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define QDECIMAL_EXPORT /* no-op */
|
||||
#endif
|
||||
|
||||
class QDECIMAL_EXPORT QDecContext;
|
||||
class QDECIMAL_EXPORT QDecNumber;
|
||||
class QDECIMAL_EXPORT QDecPacked;
|
||||
class QDECIMAL_EXPORT QDecSingle;
|
||||
class QDECIMAL_EXPORT QDecDouble;
|
||||
class QDECIMAL_EXPORT QDecQuad;
|
||||
|
||||
#endif /* Include guard */
|
||||
@@ -0,0 +1,67 @@
|
||||
/** \file QDecNumber.cc
|
||||
* Definitions for the class QDecNumber.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "QDecNumber.hh"
|
||||
#include <stdlib.h>
|
||||
#include <QTextStream>
|
||||
#include "QDecSingle.hh"
|
||||
#include "QDecDouble.hh"
|
||||
#include "QDecQuad.hh"
|
||||
#include "QDecPacked.hh"
|
||||
extern "C" {
|
||||
#include "decimal32.h"
|
||||
#include "decimal64.h"
|
||||
#include "decimal128.h"
|
||||
}
|
||||
|
||||
|
||||
|
||||
QDecNumber::QDecNumber(const QDecSingle& s)
|
||||
{ decSingleToNumber(s.data(), &m_data); }
|
||||
|
||||
QDecNumber::QDecNumber(const QDecDouble& d)
|
||||
{ decDoubleToNumber(d.data(), &m_data); }
|
||||
|
||||
QDecNumber::QDecNumber(const QDecQuad& q)
|
||||
{ decQuadToNumber(q.data(), &m_data); }
|
||||
|
||||
QDecNumber::QDecNumber(const QDecPacked& p)
|
||||
{ *this = p.toQDecNumber(); }
|
||||
|
||||
|
||||
QDecNumber& QDecNumber::fromDouble(double d)
|
||||
{
|
||||
char str[MaxStrSize] = { 0 };
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
_snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d);
|
||||
#else
|
||||
snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d);
|
||||
#endif
|
||||
return fromString(str);
|
||||
}
|
||||
|
||||
|
||||
double QDecNumber::toDouble() const
|
||||
{
|
||||
char str[MaxStrSize] = { 0 };
|
||||
|
||||
decNumberToString(&m_data, str);
|
||||
return strtod(str, 0);
|
||||
}
|
||||
|
||||
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecNumber& n)
|
||||
{
|
||||
ts << n.toString();
|
||||
return ts;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,433 @@
|
||||
#ifndef QDECNUMBER_HH
|
||||
#define QDECNUMBER_HH
|
||||
|
||||
/** \file QDecNumber.hh
|
||||
* Declarations for the class QDecNumber.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "QDecFwd.hh"
|
||||
#include "QDecContext.hh"
|
||||
|
||||
// FORWARDS
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTextStream;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
/*!
|
||||
\class QDecNumber
|
||||
QDecNumber encapsulates decNumber and reimplements global functions
|
||||
that operates upon decNumber as member functions with the same name.
|
||||
decNumber module uses an arbitrary-precision decimal number representation
|
||||
designed for efficient computation in software and implements the
|
||||
arithmetic and logical operations, together with a number of conversions
|
||||
and utilities. Once a number is held as a decNumber, no further conversions
|
||||
are necessary to carry out arithmetic.
|
||||
The decNumber representation is variable-length and machine-dependent
|
||||
(for example, it contains integers which may be big-endian or little-endian).
|
||||
*/
|
||||
class QDECIMAL_EXPORT QDecNumber
|
||||
{
|
||||
// MEMBERS
|
||||
//! Embedded decNumber structure
|
||||
decNumber m_data;
|
||||
|
||||
public:
|
||||
// TYPES
|
||||
typedef decNumber* decNumberPtr_t;
|
||||
enum {
|
||||
MaxStrSize = QDECMAXSTRSIZE
|
||||
};
|
||||
|
||||
// CREATORS
|
||||
//! Default constructor
|
||||
QDecNumber() { decNumberZero(&m_data); }
|
||||
|
||||
// Constructors using decNumber structure
|
||||
QDecNumber(const decNumber& d) : m_data(d) {}
|
||||
QDecNumber(const decNumber* p) : m_data(*p) {}
|
||||
|
||||
// Conversion constructors using simple types
|
||||
QDecNumber(const char* str) { fromString(str); }
|
||||
// m_data must have space for the digits needed to represent
|
||||
// the value of val, which may need up to ten digits.
|
||||
QDecNumber(uint32_t val) { fromUInt32(val); }
|
||||
QDecNumber(int32_t val) { fromInt32(val); }
|
||||
QDecNumber(double d) { fromDouble(d); }
|
||||
|
||||
// Conversion constructors using composite types
|
||||
QDecNumber(const QDecSingle& s);
|
||||
QDecNumber(const QDecDouble& d);
|
||||
QDecNumber(const QDecQuad& q);
|
||||
QDecNumber(const QDecPacked& p);
|
||||
|
||||
//! Copy constructor
|
||||
QDecNumber(const QDecNumber& o)
|
||||
{ decNumberCopy(&m_data, &o.m_data); }
|
||||
|
||||
//! Copy assignment
|
||||
QDecNumber& operator=(const QDecNumber& o)
|
||||
{ if(this != &o) decNumberCopy(&m_data, &o.m_data); return *this; }
|
||||
|
||||
//! Type conversion operator to decNumber*
|
||||
operator decNumberPtr_t() { return &m_data; }
|
||||
|
||||
|
||||
// ACCESSORS
|
||||
const decNumber* data() const
|
||||
{ return &m_data; }
|
||||
|
||||
// MODIFIERS
|
||||
decNumber* data()
|
||||
{ return &m_data; }
|
||||
|
||||
|
||||
// CONVERSIONS
|
||||
QDecNumber& fromBCD(QByteArray& bcd) {
|
||||
decNumberSetBCD(&m_data, (const uint8_t*)bcd.data(), bcd.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecNumber& fromDouble(double d);
|
||||
|
||||
QDecNumber& fromInt32(int32_t val)
|
||||
{ decNumberFromInt32(&m_data, val); return *this; }
|
||||
|
||||
QDecNumber& fromUInt32(uint32_t val)
|
||||
{ decNumberFromUInt32(&m_data, val); return *this; }
|
||||
|
||||
QDecNumber& fromString(const char* str, QDecContext* c = 0)
|
||||
{ decNumberFromString(&m_data, str, CXT(c)); return *this; }
|
||||
|
||||
QByteArray toBCD() const {
|
||||
QByteArray bcd(m_data.digits+1, '\0');
|
||||
decNumberGetBCD(&m_data, (uint8_t*)bcd.data());
|
||||
return bcd;
|
||||
}
|
||||
|
||||
double toDouble() const;
|
||||
|
||||
QByteArray toEngString() const {
|
||||
char str[MaxStrSize] = { 0 };
|
||||
return decNumberToEngString(&m_data, str);
|
||||
}
|
||||
|
||||
QByteArray toString() const {
|
||||
char str[MaxStrSize] = { 0 };
|
||||
return decNumberToString(&m_data, str);
|
||||
}
|
||||
|
||||
int32_t toInt32(QDecContext* c = 0) const
|
||||
{ return decNumberToInt32(&m_data, CXT(c)); }
|
||||
|
||||
uint32_t toUInt32(QDecContext* c = 0) const
|
||||
{ return decNumberToUInt32(&m_data, CXT(c)); }
|
||||
|
||||
|
||||
// COMPUTATIONAL FUNCTIONS
|
||||
QDecNumber abs(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberAbs(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber add(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberAdd(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber digitAnd(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberAnd(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber compare(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberCompare(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber compareSignal(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberCompareSignal(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber compareTotal(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberCompareTotal(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber compareTotalMag(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberCompareTotalMag(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber divide(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberDivide(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber divideInteger(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberDivideInteger(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber exp(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberExp(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber fma(const QDecNumber& mo, const QDecNumber& ao,
|
||||
QDecContext* c = 0) const {
|
||||
decNumber n;
|
||||
return decNumberFMA(&n, &m_data, &mo.m_data, &ao.m_data, CXT(c));
|
||||
}
|
||||
|
||||
QDecNumber invert(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberInvert(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber ln(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberLn(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber logB(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberLogB(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber log10(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberLog10(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber max(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberMax(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber maxMag(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberMaxMag(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber min(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberMin(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber minMag(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberMinMag(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber minus(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberMinus(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber multiply(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberMultiply(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber nextMinus(QDecContext* c = 0)
|
||||
{ decNumber n; return decNumberNextMinus(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber nextPlus(QDecContext* c = 0)
|
||||
{ decNumber n; return decNumberNextPlus(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber nextToward(const QDecNumber& o, QDecContext* c = 0)
|
||||
{ decNumber n; return decNumberNextToward(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber normalize(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberNormalize(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber digitOr(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberOr(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber plus(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberPlus(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber power(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberPower(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber quantize(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberQuantize(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber reduce(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberReduce(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber remainder(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberRemainder(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber remainderNear(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberRemainderNear(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber rescale(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberRescale(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber rotate(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberRotate(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
bool sameQuantum(const QDecNumber& o) const {
|
||||
decNumber n;
|
||||
QDecNumber r = decNumberSameQuantum(&n, data(), o.data());
|
||||
return !r.isZero();
|
||||
}
|
||||
|
||||
QDecNumber scaleB(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberScaleB(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber shift(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberShift(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber squareRoot(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberSquareRoot(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber subtract(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberSubtract(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecNumber toIntegralExact(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberToIntegralExact(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber toIntegralValue(QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberToIntegralValue(&n, &m_data, CXT(c)); }
|
||||
|
||||
QDecNumber digitXor(const QDecNumber& o, QDecContext* c = 0) const
|
||||
{ decNumber n; return decNumberXor(&n, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
|
||||
// TESTING FUNCTIONS
|
||||
bool isCanonical() const
|
||||
{ return decNumberIsCanonical(&m_data); }
|
||||
|
||||
bool isFinite() const
|
||||
{ return decNumberIsFinite(&m_data); }
|
||||
|
||||
bool isInfinite() const
|
||||
{ return decNumberIsInfinite(&m_data); }
|
||||
|
||||
bool isNaN() const
|
||||
{ return decNumberIsNaN(&m_data); }
|
||||
|
||||
bool isNegative() const
|
||||
{ return decNumberIsNegative(&m_data); }
|
||||
|
||||
bool isQNaN() const
|
||||
{ return decNumberIsQNaN(&m_data); }
|
||||
|
||||
bool isSNaN() const
|
||||
{ return decNumberIsSNaN(&m_data); }
|
||||
|
||||
bool isSpecial() const
|
||||
{ return decNumberIsSpecial(&m_data); }
|
||||
|
||||
bool isZero() const
|
||||
{ return decNumberIsZero(&m_data); }
|
||||
|
||||
|
||||
// TEST FUNCTIONS (CONTEXT DEPENDENT)
|
||||
bool isNormal(QDecContext* c = 0) const
|
||||
{ return decNumberIsNormal(&m_data, CXT(c)); }
|
||||
|
||||
bool isSubnormal(QDecContext* c = 0) const
|
||||
{ return decNumberIsSubnormal(&m_data, CXT(c)); }
|
||||
|
||||
|
||||
|
||||
// UTILITIES
|
||||
enum decClass toClass(QDecContext* c = 0) const
|
||||
{ return decNumberClass(&m_data, CXT(c)); }
|
||||
|
||||
QDecNumber& copy(const QDecNumber& o)
|
||||
{ decNumberCopy(&m_data, &o.m_data); return *this; }
|
||||
|
||||
QDecNumber& copyAbs(const QDecNumber& o)
|
||||
{ decNumberCopyAbs(&m_data, &o.m_data); return *this; }
|
||||
|
||||
QDecNumber& copyNegate(const QDecNumber& o)
|
||||
{ decNumberCopyNegate(&m_data, &o.m_data); return *this; }
|
||||
|
||||
QDecNumber& copySign(const QDecNumber& o, const QDecNumber& so)
|
||||
{ decNumberCopySign(&m_data, &o.m_data, &so.m_data); return *this; }
|
||||
|
||||
uint32_t radix() const
|
||||
{ return decNumberRadix(&m_data); }
|
||||
|
||||
QDecNumber& trim()
|
||||
{ decNumberTrim(&m_data); return *this; }
|
||||
|
||||
const char* version() const
|
||||
{ return decNumberVersion(); }
|
||||
|
||||
QDecNumber& zero()
|
||||
{ decNumberZero(&m_data); return *this; }
|
||||
|
||||
|
||||
// STATIC FUNCTIONS (UTILITIES)
|
||||
static const char* ClassToString(enum decClass dc)
|
||||
{ return decNumberClassToString(dc); }
|
||||
|
||||
static const char* Version()
|
||||
{ return decNumberVersion(); }
|
||||
|
||||
|
||||
// RELATIONAL AND LOGICAL OPERATORS
|
||||
bool operator==(const QDecNumber& o) const
|
||||
{ return compare(o).isZero(); }
|
||||
|
||||
bool operator!=(const QDecNumber& o) const
|
||||
{ return !(this->operator==(o)); }
|
||||
|
||||
bool operator<(const QDecNumber& o) const
|
||||
{ return compare(o).isNegative(); }
|
||||
|
||||
bool operator<=(const QDecNumber& o) const
|
||||
{
|
||||
const QDecNumber& r = compare(o);
|
||||
return r.isNegative() || r.isZero();
|
||||
}
|
||||
|
||||
bool operator>(const QDecNumber& o) const
|
||||
{ return !(this->operator<=(o)); }
|
||||
|
||||
bool operator>=(const QDecNumber& o) const
|
||||
{
|
||||
const QDecNumber& r = compare(o);
|
||||
return !r.isNegative() || r.isZero();
|
||||
}
|
||||
|
||||
// BITWISE OPERATORS
|
||||
QDecNumber operator&(const QDecNumber& o) const
|
||||
{ return digitAnd(o); }
|
||||
|
||||
QDecNumber operator|(const QDecNumber& o) const
|
||||
{ return digitOr(o); }
|
||||
|
||||
QDecNumber operator^(const QDecNumber& o) const
|
||||
{ return digitXor(o); }
|
||||
|
||||
|
||||
// ARITHMETIC OPERATORS
|
||||
QDecNumber operator+(const QDecNumber& o) const
|
||||
{ return add(o); }
|
||||
|
||||
QDecNumber operator-(const QDecNumber& o) const
|
||||
{ return subtract(o); }
|
||||
|
||||
QDecNumber operator*(const QDecNumber& o) const
|
||||
{ return multiply(o); }
|
||||
|
||||
QDecNumber operator/(const QDecNumber& o) const
|
||||
{ return divide(o); }
|
||||
|
||||
QDecNumber operator%(const QDecNumber& o) const
|
||||
{ return remainder(o); }
|
||||
|
||||
|
||||
// COMPOUND ASSIGNMENT OPERATORS
|
||||
QDecNumber& operator+=(const QDecNumber& o)
|
||||
{ return copy(add(o)); }
|
||||
|
||||
QDecNumber& operator-=(const QDecNumber& o)
|
||||
{ return copy(subtract(o)); }
|
||||
|
||||
QDecNumber& operator*=(const QDecNumber& o)
|
||||
{ return copy(multiply(o)); }
|
||||
|
||||
QDecNumber& operator/=(const QDecNumber& o)
|
||||
{ return copy(divide(o)); }
|
||||
|
||||
QDecNumber& operator%=(const QDecNumber& o)
|
||||
{ return copy(remainder(o)); }
|
||||
|
||||
QDecNumber& operator&=(const QDecNumber& o)
|
||||
{ return copy(digitAnd(o)); }
|
||||
|
||||
QDecNumber& operator|=(const QDecNumber& o)
|
||||
{ return copy(digitOr(o)); }
|
||||
|
||||
QDecNumber& operator^=(const QDecNumber& o)
|
||||
{ return copy(digitXor(o)); }
|
||||
|
||||
|
||||
}; // end class
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(QDecNumber);
|
||||
|
||||
QDECIMAL_EXPORT
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecNumber& n);
|
||||
|
||||
#endif /* Include guard */
|
||||
@@ -0,0 +1,83 @@
|
||||
/** \file QDecPacked.cc
|
||||
* Definitions for the class QDecPacked.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "QDecPacked.hh"
|
||||
#include "QDecNumber.hh"
|
||||
#include "QDecSingle.hh"
|
||||
#include "QDecDouble.hh"
|
||||
#include "QDecQuad.hh"
|
||||
|
||||
QDecPacked::QDecPacked(const char* str)
|
||||
{ *this = fromQDecNumber(QDecNumber(str)); }
|
||||
|
||||
QDecPacked::QDecPacked(double d)
|
||||
{ *this = fromQDecNumber(QDecNumber(d)); }
|
||||
|
||||
QDecPacked::QDecPacked(const QDecSingle& s)
|
||||
{ *this = s.toQDecPacked(); }
|
||||
|
||||
QDecPacked::QDecPacked(const QDecDouble& d)
|
||||
{ *this = d.toQDecPacked(); }
|
||||
|
||||
QDecPacked::QDecPacked(const QDecQuad& q)
|
||||
{ *this = q.toQDecPacked(); }
|
||||
|
||||
|
||||
QDecPacked& QDecPacked::fromQDecNumber(const QDecNumber& d)
|
||||
{
|
||||
uint8_t bfr[QDecNumDigits] = { 0 };
|
||||
int32_t scale = 0;
|
||||
|
||||
uint8_t* rv = decPackedFromNumber(bfr, QDecNumDigits, &scale, d.data());
|
||||
|
||||
if(rv) {
|
||||
m_scale = scale;
|
||||
|
||||
char* p = (char*)bfr;
|
||||
int i = 0;
|
||||
// Skip null bytes at the left
|
||||
for(; p[i] == '\0' || i==QDecNumDigits; ++i);
|
||||
|
||||
// Construct byte array from the beginning of BCD bytes
|
||||
m_bytes = QByteArray(&p[i], QDecNumDigits-i);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecNumber QDecPacked::toQDecNumber() const
|
||||
{
|
||||
if(length() > 0) {
|
||||
decNumber n;
|
||||
return decPackedToNumber(bytesRaw(), length(), &m_scale, &n);
|
||||
}
|
||||
else
|
||||
// Not initialized, return default QDecNumber value
|
||||
return QDecNumber();
|
||||
}
|
||||
|
||||
QDecPacked& QDecPacked::fromDouble(double d)
|
||||
{
|
||||
*this = fromQDecNumber(QDecNumber(d));
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecPacked& QDecPacked::fromString(const char* str)
|
||||
{
|
||||
*this = fromQDecNumber(QDecNumber(str));
|
||||
return *this;
|
||||
}
|
||||
|
||||
QByteArray QDecPacked::toString() const
|
||||
{
|
||||
return toQDecNumber().toString();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
#ifndef QDECPACKED_HH
|
||||
#define QDECPACKED_HH
|
||||
|
||||
/** \file QDecPacked.hh
|
||||
* Declarations for the class QDecPacked.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
#include "QDecFwd.hh"
|
||||
extern "C" {
|
||||
#include "decPacked.h"
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\class QDecPacked
|
||||
QDecPacked augments decPacked by encapsulating reference counted byte
|
||||
array and scale of the decimal point as members variables, thus, freeing up
|
||||
user of this class from memory management and keeping track of scale value.
|
||||
The decPacked format is the classic packed decimal format implemented
|
||||
by IBM S/360 and later machines, where each digit is encoded as
|
||||
a 4-bit binary sequence (BCD) and a number is ended by a 4-bit
|
||||
sign indicator. The decPacked module accepts variable lengths,
|
||||
allowing for very large numbers (up to a billion digits), and also
|
||||
allows the specification of a scale.
|
||||
*/
|
||||
class QDECIMAL_EXPORT QDecPacked
|
||||
{
|
||||
// MEMBERS
|
||||
//! Byte array containing BCD sequence
|
||||
QByteArray m_bytes;
|
||||
//! Scale of the decimal number (point)
|
||||
int32_t m_scale;
|
||||
|
||||
public:
|
||||
// CREATORS
|
||||
//! Default constructor
|
||||
QDecPacked() : m_scale(0) {}
|
||||
QDecPacked(int32_t length, int32_t scale = 0)
|
||||
: m_bytes(length,'\0'), m_scale(scale) {}
|
||||
QDecPacked(const QByteArray& bytes, int32_t scale = 0)
|
||||
: m_bytes(bytes), m_scale(scale) {}
|
||||
|
||||
// Default copy constructor and destructor are ok to use
|
||||
|
||||
// Conversion constructors using simple types
|
||||
QDecPacked(const char* str);
|
||||
QDecPacked(double d);
|
||||
|
||||
// Conversion constructors using composite types
|
||||
QDecPacked(const QDecNumber& d) { fromQDecNumber(d); }
|
||||
QDecPacked(const QDecSingle& s);
|
||||
QDecPacked(const QDecDouble& d);
|
||||
QDecPacked(const QDecQuad& d);
|
||||
|
||||
// ACCESSORS
|
||||
const char* data() const
|
||||
{ return m_bytes.data(); }
|
||||
|
||||
QByteArray bytes() const
|
||||
{ return m_bytes; }
|
||||
|
||||
const uint8_t* bytesRaw() const
|
||||
{ return reinterpret_cast<const uint8_t*>(m_bytes.data()); }
|
||||
|
||||
int32_t length() const
|
||||
{ return m_bytes.size(); }
|
||||
|
||||
int32_t scale() const
|
||||
{ return m_scale; }
|
||||
|
||||
QByteArray toString() const;
|
||||
|
||||
|
||||
// MODIFIERS
|
||||
uint8_t* bytesRaw()
|
||||
{ return reinterpret_cast<uint8_t*>(m_bytes.data()); }
|
||||
|
||||
QDecPacked& fromDouble(double d);
|
||||
|
||||
QDecPacked& fromString(const char* str);
|
||||
|
||||
void setLength(int32_t length)
|
||||
{ m_bytes.resize(length); }
|
||||
|
||||
void setScale(int32_t scale)
|
||||
{ m_scale = scale; }
|
||||
|
||||
// CONVERSIONS
|
||||
QDecNumber toQDecNumber() const;
|
||||
QDecPacked& fromQDecNumber(const QDecNumber& d);
|
||||
|
||||
|
||||
}; // end class
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* Include guard */
|
||||
@@ -0,0 +1,100 @@
|
||||
/** \file QDecQuad.cc
|
||||
* Definitions for the class QDecQuad.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id: QDecQuad.cc 111 2006-06-19 03:45:40Z semihc $
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "QDecQuad.hh"
|
||||
extern "C" {
|
||||
#include "decimal128.h"
|
||||
}
|
||||
#include <stdlib.h>
|
||||
#include <QTextStream>
|
||||
#include "QDecNumber.hh"
|
||||
#include "QDecPacked.hh"
|
||||
#include "QDecDouble.hh"
|
||||
|
||||
|
||||
QDecQuad& QDecQuad::fromDouble(double d)
|
||||
{
|
||||
char str[MaxStrSize] = { 0 };
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
_snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d);
|
||||
#else
|
||||
snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d);
|
||||
#endif
|
||||
|
||||
return fromString(str);
|
||||
}
|
||||
|
||||
|
||||
QDecQuad& QDecQuad::fromHexString(const char* str)
|
||||
{
|
||||
QByteArray ba = QByteArray::fromHex(str);
|
||||
int size = sizeof(m_data);
|
||||
char* p = (char*)&m_data;
|
||||
int i = 0;
|
||||
int j = size-1;
|
||||
for(; i<size; i++,j--)
|
||||
p[j] = ba.at(i);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
QDecQuad& QDecQuad::fromQDecDouble(const QDecDouble& d)
|
||||
{
|
||||
decDoubleToWider(d.data(), &m_data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecQuad& QDecQuad::fromQDecNumber(const QDecNumber& n, QDecContext* c)
|
||||
{
|
||||
decQuadFromNumber(&m_data, n.data(), CXT(c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecQuad& QDecQuad::fromQDecPacked(const QDecPacked& p)
|
||||
{
|
||||
fromQDecNumber(p.toQDecNumber());
|
||||
return *this;
|
||||
}
|
||||
|
||||
double QDecQuad::toDouble() const
|
||||
{
|
||||
char str[MaxStrSize] = { 0 };
|
||||
decQuadToString(&m_data, str);
|
||||
return strtod(str, 0);
|
||||
}
|
||||
|
||||
QDecDouble QDecQuad::toQDecDouble(QDecContext* c) const
|
||||
{
|
||||
decDouble d;
|
||||
return decDoubleFromWider(&d, &m_data, CXT(c));
|
||||
}
|
||||
|
||||
QDecPacked QDecQuad::toQDecPacked() const
|
||||
{
|
||||
return QDecPacked(toQDecNumber());
|
||||
}
|
||||
|
||||
QDecNumber QDecQuad::toQDecNumber() const
|
||||
{
|
||||
decNumber n;
|
||||
return decQuadToNumber(&m_data, &n);
|
||||
}
|
||||
|
||||
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecQuad& d)
|
||||
{
|
||||
ts << d.toString();
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,442 @@
|
||||
#ifndef QDECQUAD_HH
|
||||
#define QDECQUAD_HH
|
||||
|
||||
/** \file QDecQuad.hh
|
||||
* Declarations for the class QDecQuad.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "QDecFwd.hh"
|
||||
#include "QDecContext.hh"
|
||||
extern "C" {
|
||||
#include "decQuad.h"
|
||||
}
|
||||
|
||||
// FORWARDS
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTextStream;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
/*!
|
||||
\class QDecQuad
|
||||
QDecQuad encapsulates decQuad and provides decNumber library functions
|
||||
that operates upon decSingle as member functions with the same name.
|
||||
decimal128 is a 128-bit decimal floating-point representation which
|
||||
provides 34 decimal digits of precision in a compressed format.
|
||||
decQuad module provides the functions for the decimal128 format;
|
||||
this format is an IEEE 754 basic format; it contains the same set of
|
||||
functions as decDouble.
|
||||
*/
|
||||
class QDECIMAL_EXPORT QDecQuad
|
||||
{
|
||||
// MEMBERS
|
||||
//! Embedded decQuad structure
|
||||
decQuad m_data;
|
||||
|
||||
public:
|
||||
// TYPES
|
||||
typedef decQuad* decQuadPtr_t;
|
||||
enum {
|
||||
MaxStrSize = QDECMAXSTRSIZE
|
||||
};
|
||||
|
||||
// CREATORS
|
||||
//! Default constructor
|
||||
QDecQuad() { decQuadZero(&m_data); }
|
||||
|
||||
// Default Dtor and Copy Ctor are ok
|
||||
|
||||
// Constructors using decQuad structure
|
||||
QDecQuad(decQuad d) : m_data(d) {}
|
||||
QDecQuad(const decQuad* p) : m_data(*p) {}
|
||||
|
||||
// Conversion constructors using simple types
|
||||
QDecQuad(const char* str) { fromString(str); }
|
||||
QDecQuad(int32_t i) { fromInt32(i); }
|
||||
QDecQuad(uint32_t i) { fromUInt32(i); }
|
||||
QDecQuad(double d) { fromDouble(d); }
|
||||
|
||||
|
||||
// Conversion constructors using composite types
|
||||
QDecQuad(const QDecDouble& d) { fromQDecDouble(d); }
|
||||
QDecQuad(const QDecPacked& p) { fromQDecPacked(p); }
|
||||
QDecQuad(const QDecNumber& n) { fromQDecNumber(n); }
|
||||
|
||||
|
||||
//! Copy assignment
|
||||
QDecQuad& operator=(const QDecQuad& o)
|
||||
{ return (this != &o ? copy(o) : *this); }
|
||||
|
||||
//! Conversion operator to decQuad*
|
||||
operator decQuadPtr_t() { return &m_data; }
|
||||
|
||||
|
||||
// ACCESSORS
|
||||
const decQuad* data() const
|
||||
{ return &m_data; }
|
||||
|
||||
// MODIFIERS
|
||||
decQuad* data()
|
||||
{ return &m_data; }
|
||||
|
||||
// UTILITIES & CONVERSIONS
|
||||
QDecQuad& fromBCD(int32_t exp, const QByteArray& bcd, int32_t sign) {
|
||||
decQuadFromBCD(&m_data, exp, (const uint8_t*)bcd.data(), sign);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecQuad& fromDouble(double d);
|
||||
|
||||
QDecQuad& fromInt32(int32_t i)
|
||||
{ decQuadFromInt32(&m_data, i); return *this; }
|
||||
|
||||
QDecQuad& fromPacked(int32_t exp, const QByteArray& pack) {
|
||||
decQuadFromPacked(&m_data, exp, (const uint8_t*)pack.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecQuad& fromPackedChecked(int32_t exp, const QByteArray& pack) {
|
||||
decQuadFromPackedChecked(&m_data, exp, (const uint8_t*)pack.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecQuad& fromString(const char* str, QDecContext* c = 0)
|
||||
{ decQuadFromString(&m_data, str, CXT(c)); return *this; }
|
||||
|
||||
//! Hexadecimal string in network byte order
|
||||
QDecQuad& fromHexString(const char* str);
|
||||
|
||||
QDecQuad& fromQDecDouble(const QDecDouble& d);
|
||||
|
||||
QDecQuad& fromQDecNumber(const QDecNumber& n, QDecContext* c = 0);
|
||||
|
||||
QDecQuad& fromQDecPacked(const QDecPacked& p);
|
||||
|
||||
QDecQuad& fromUInt32(uint32_t i)
|
||||
{ decQuadFromUInt32(&m_data, i); return *this; }
|
||||
|
||||
int32_t getCoefficient(QByteArray& bcd) const {
|
||||
bcd.resize(DECQUAD_Pmax);
|
||||
return decQuadGetCoefficient(&m_data, (uint8_t*)bcd.data());
|
||||
}
|
||||
|
||||
QDecQuad& setCoefficient(const QByteArray& bcd, int32_t sign) {
|
||||
decQuadSetCoefficient(&m_data, (const uint8_t*)bcd.data(), sign);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecQuad& setExponent(int32_t exp, QDecContext* c = 0) {
|
||||
decQuadSetExponent(&m_data, CXT(c), exp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int32_t toBCD(int32_t& exp, QByteArray& bcd) {
|
||||
bcd.resize(DECQUAD_Pmax);
|
||||
return decQuadToBCD(&m_data, &exp, (uint8_t*)bcd.data());
|
||||
}
|
||||
|
||||
double toDouble() const;
|
||||
|
||||
QByteArray toEngString() const {
|
||||
char str[MaxStrSize] = { 0 };
|
||||
return decQuadToEngString(&m_data, str);
|
||||
}
|
||||
|
||||
int32_t toPacked(int32_t& exp, QByteArray& pack) {
|
||||
pack.resize(DECQUAD_Pmax);
|
||||
return decQuadToPacked(&m_data, &exp, (uint8_t*)pack.data());
|
||||
}
|
||||
|
||||
QByteArray toString() const {
|
||||
char str[MaxStrSize] = { 0 };
|
||||
return decQuadToString(&m_data, str);
|
||||
}
|
||||
|
||||
QDecDouble toQDecDouble(QDecContext* c = 0) const;
|
||||
|
||||
QDecPacked toQDecPacked() const;
|
||||
|
||||
QDecNumber toQDecNumber() const;
|
||||
|
||||
QDecQuad& zero()
|
||||
{ decQuadZero(&m_data); return *this; }
|
||||
|
||||
|
||||
// COMPUTATIONAL
|
||||
QDecQuad abs(QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadAbs(&q, &m_data, CXT(c)); }
|
||||
|
||||
QDecQuad add(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadAdd(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad digitAnd(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadAnd(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad divide(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadDivide(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad divideInteger(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadDivideInteger(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad fma(const QDecQuad& o, const QDecQuad& o2,
|
||||
QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadFMA(&q, &m_data, &o.m_data, &o2.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad invert(QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadInvert(&q, &m_data, CXT(c)); }
|
||||
|
||||
QDecQuad logB(QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadLogB(&q, &m_data, CXT(c)); }
|
||||
|
||||
QDecQuad max(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadMax(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad maxMag(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadMaxMag(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad minus(QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadMinus(&q, &m_data, CXT(c)); }
|
||||
|
||||
QDecQuad multiply(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadMultiply(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad nextMinus(QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadNextMinus(&q, &m_data, CXT(c)); }
|
||||
|
||||
QDecQuad nextPlus(QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadNextPlus(&q, &m_data, CXT(c)); }
|
||||
|
||||
QDecQuad nextToward(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadNextToward(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad digitOr(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadOr(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad plus(QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadPlus(&q, &m_data, CXT(c)); }
|
||||
|
||||
QDecQuad quantize(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadQuantize(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad reduce(QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadReduce(&q, &m_data, CXT(c)); }
|
||||
|
||||
QDecQuad remainder(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadRemainder(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad remainderNear(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadRemainderNear(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad rotate(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadRotate(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad scaleB(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadScaleB(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad shift(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadShift(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad subtract(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadSubtract(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad toIntegralValue(enum rounding r, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadToIntegralValue(&q, &m_data, CXT(c), r); }
|
||||
|
||||
QDecQuad toIntegralExact(QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadToIntegralExact(&q, &m_data, CXT(c)); }
|
||||
|
||||
QDecQuad digitXor(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadXor(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
|
||||
// COMPARISONS
|
||||
QDecQuad compare(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadCompare(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad compareSignal(const QDecQuad& o, QDecContext* c = 0) const
|
||||
{ decQuad q; return decQuadCompareSignal(&q, &m_data, &o.m_data, CXT(c)); }
|
||||
|
||||
QDecQuad compareTotal(const QDecQuad& o) const
|
||||
{ decQuad q; return decQuadCompareTotal(&q, &m_data, &o.m_data); }
|
||||
|
||||
QDecQuad compareTotalMag(const QDecQuad& o) const
|
||||
{ decQuad q; return decQuadCompareTotalMag(&q, &m_data, &o.m_data); }
|
||||
|
||||
|
||||
// COPIES
|
||||
QDecQuad& canonical(const QDecQuad& d)
|
||||
{ decQuadCanonical(&m_data, &d.m_data); return *this; }
|
||||
|
||||
QDecQuad& copy(const QDecQuad& d)
|
||||
{ decQuadCopy(&m_data, &d.m_data); return *this; }
|
||||
|
||||
QDecQuad& copyAbs(const QDecQuad& d)
|
||||
{ decQuadCopyAbs(&m_data, &d.m_data); return *this; }
|
||||
|
||||
QDecQuad& copyNegate(const QDecQuad& d)
|
||||
{ decQuadCopyNegate(&m_data, &d.m_data); return *this; }
|
||||
|
||||
QDecQuad& copySign(const QDecQuad& d, const QDecQuad& sd)
|
||||
{ decQuadCopySign(&m_data, &d.m_data, &sd.m_data); return *this; }
|
||||
|
||||
|
||||
// NON-COMPUTATIONAL
|
||||
// "class" is a reserved word in C++
|
||||
enum decClass classification() const
|
||||
{ return decQuadClass(&m_data); }
|
||||
|
||||
const char* classString() const
|
||||
{ return decQuadClassString(&m_data); }
|
||||
|
||||
uint32_t digits() const
|
||||
{ return decQuadDigits(&m_data); }
|
||||
|
||||
bool isCanonical() const
|
||||
{ return decQuadIsCanonical(&m_data); }
|
||||
|
||||
bool isFinite() const
|
||||
{ return decQuadIsFinite(&m_data); }
|
||||
|
||||
bool isInteger() const
|
||||
{ return decQuadIsInteger(&m_data); }
|
||||
|
||||
bool isLogical() const
|
||||
{ return decQuadIsLogical(&m_data); }
|
||||
|
||||
bool isInfinite() const
|
||||
{ return decQuadIsInfinite(&m_data); }
|
||||
|
||||
bool isNaN() const
|
||||
{ return decQuadIsNaN(&m_data); }
|
||||
|
||||
bool isNegative() const
|
||||
{ return decQuadIsNegative(&m_data); }
|
||||
|
||||
bool isNormal() const
|
||||
{ return decQuadIsNormal(&m_data); }
|
||||
|
||||
bool isPositive() const
|
||||
{ return decQuadIsPositive(&m_data); }
|
||||
|
||||
bool isSignaling() const
|
||||
{ return decQuadIsSignaling(&m_data); }
|
||||
|
||||
bool isSignalling() const
|
||||
{ return decQuadIsSignalling(&m_data); }
|
||||
|
||||
bool isSigned() const
|
||||
{ return decQuadIsSigned(&m_data); }
|
||||
|
||||
bool isSubnormal() const
|
||||
{ return decQuadIsSubnormal(&m_data); }
|
||||
|
||||
bool isZero() const
|
||||
{ return decQuadIsZero(&m_data); }
|
||||
|
||||
uint32_t radix() const
|
||||
{ return decQuadRadix(&m_data); }
|
||||
|
||||
const char* version() const
|
||||
{ return decQuadVersion(); }
|
||||
|
||||
|
||||
// RELATIONAL AND LOGICAL OPERATORS
|
||||
bool operator==(const QDecQuad& o) const
|
||||
{ return compare(o).isZero(); }
|
||||
|
||||
bool operator!=(const QDecQuad& o) const
|
||||
{ return !(this->operator==(o)); }
|
||||
|
||||
bool operator<(const QDecQuad& o) const
|
||||
{ return compare(o).isNegative(); }
|
||||
|
||||
bool operator<=(const QDecQuad& o) const
|
||||
{
|
||||
const QDecQuad& r = compare(o);
|
||||
return r.isNegative() || r.isZero();
|
||||
}
|
||||
|
||||
bool operator>(const QDecQuad& o) const
|
||||
{ return !(this->operator<=(o)); }
|
||||
|
||||
bool operator>=(const QDecQuad& o) const
|
||||
{
|
||||
const QDecQuad& r = compare(o);
|
||||
return !r.isNegative() || r.isZero();
|
||||
}
|
||||
|
||||
// BITWISE OPERATORS
|
||||
QDecQuad operator&(const QDecQuad& o) const
|
||||
{ return digitAnd(o); }
|
||||
|
||||
QDecQuad operator|(const QDecQuad& o) const
|
||||
{ return digitOr(o); }
|
||||
|
||||
QDecQuad operator^(const QDecQuad& o) const
|
||||
{ return digitXor(o); }
|
||||
|
||||
|
||||
// ARITHMETIC OPERATORS
|
||||
QDecQuad operator+(const QDecQuad& o) const
|
||||
{ return add(o); }
|
||||
|
||||
QDecQuad operator-(const QDecQuad& o) const
|
||||
{ return subtract(o); }
|
||||
|
||||
QDecQuad operator*(const QDecQuad& o) const
|
||||
{ return multiply(o); }
|
||||
|
||||
QDecQuad operator/(const QDecQuad& o) const
|
||||
{ return divide(o); }
|
||||
|
||||
QDecQuad operator%(const QDecQuad& o) const
|
||||
{ return remainder(o); }
|
||||
|
||||
|
||||
// COMPOUND ASSIGNMENT OPERATORS
|
||||
QDecQuad& operator+=(const QDecQuad& o)
|
||||
{ return copy(add(o)); }
|
||||
|
||||
QDecQuad& operator-=(const QDecQuad& o)
|
||||
{ return copy(subtract(o)); }
|
||||
|
||||
QDecQuad& operator*=(const QDecQuad& o)
|
||||
{ return copy(multiply(o)); }
|
||||
|
||||
QDecQuad& operator/=(const QDecQuad& o)
|
||||
{ return copy(divide(o)); }
|
||||
|
||||
QDecQuad& operator%=(const QDecQuad& o)
|
||||
{ return copy(remainder(o)); }
|
||||
|
||||
QDecQuad& operator&=(const QDecQuad& o)
|
||||
{ return copy(digitAnd(o)); }
|
||||
|
||||
QDecQuad& operator|=(const QDecQuad& o)
|
||||
{ return copy(digitOr(o)); }
|
||||
|
||||
QDecQuad& operator^=(const QDecQuad& o)
|
||||
{ return copy(digitXor(o)); }
|
||||
|
||||
|
||||
}; // end class
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(QDecQuad);
|
||||
|
||||
|
||||
QDECIMAL_EXPORT
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecQuad& d);
|
||||
|
||||
|
||||
#endif /* Include guard */
|
||||
@@ -0,0 +1,102 @@
|
||||
/** \file QDecSingle.cc
|
||||
* Definitions for the class QDecSingle.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "QDecSingle.hh"
|
||||
extern "C" {
|
||||
#include "decimal32.h"
|
||||
}
|
||||
#include <stdlib.h>
|
||||
#include <QTextStream>
|
||||
#include "QDecNumber.hh"
|
||||
#include "QDecPacked.hh"
|
||||
#include "QDecDouble.hh"
|
||||
|
||||
|
||||
QDecSingle& QDecSingle::fromDouble(double d)
|
||||
{
|
||||
char str[MaxStrSize] = {0};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
_snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d);
|
||||
#else
|
||||
snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d);
|
||||
#endif
|
||||
|
||||
return fromString(str);
|
||||
}
|
||||
|
||||
QDecSingle& QDecSingle::fromHexString(const char* str)
|
||||
{
|
||||
QByteArray ba = QByteArray::fromHex(str);
|
||||
int size = sizeof(m_data);
|
||||
char* p = (char*)&m_data;
|
||||
int i = 0;
|
||||
int j = size-1;
|
||||
for(; i<size; i++,j--)
|
||||
p[j] = ba.at(i);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
QDecSingle& QDecSingle::fromQDecNumber(const QDecNumber& n, QDecContext* c)
|
||||
{
|
||||
decSingleFromNumber(&m_data, n.data(), CXT(c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecSingle& QDecSingle::fromQDecPacked(const QDecPacked& p)
|
||||
{
|
||||
fromQDecNumber(p.toQDecNumber());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecSingle& QDecSingle::fromWider(const QDecDouble& d, QDecContext* c)
|
||||
{
|
||||
decSingleFromWider(&m_data, d.data(), CXT(c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
double QDecSingle::toDouble() const
|
||||
{
|
||||
char str[MaxStrSize] = {0};
|
||||
decSingleToString(&m_data, str);
|
||||
return strtod(str, 0);
|
||||
}
|
||||
|
||||
QDecDouble QDecSingle::toQDecDouble() const
|
||||
{
|
||||
return toWider();
|
||||
}
|
||||
|
||||
QDecPacked QDecSingle::toQDecPacked() const
|
||||
{
|
||||
return QDecPacked(toQDecNumber());
|
||||
}
|
||||
|
||||
QDecNumber QDecSingle::toQDecNumber() const
|
||||
{
|
||||
decNumber n;
|
||||
return decSingleToNumber(&m_data, &n);
|
||||
}
|
||||
|
||||
QDecDouble QDecSingle::toWider() const
|
||||
{
|
||||
decDouble d;
|
||||
return decSingleToWider(&m_data, &d);
|
||||
}
|
||||
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecSingle& d)
|
||||
{
|
||||
ts << d.toString();
|
||||
return ts;
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
#ifndef QDECSINGLE_HH
|
||||
#define QDECSINGLE_HH
|
||||
|
||||
/** \file QDecSingle.hh
|
||||
* Declarations for the class QDecSingle.
|
||||
*
|
||||
* (C) Copyright by Semih Cemiloglu
|
||||
* All rights reserved, see COPYRIGHT file for details.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "QDecFwd.hh"
|
||||
#include "QDecContext.hh"
|
||||
extern "C" {
|
||||
#include "decSingle.h"
|
||||
}
|
||||
|
||||
// FORWARDS
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTextStream;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
/*!
|
||||
\class QDecSingle
|
||||
QDecSingle encapsulates decSingle and provides decNumber
|
||||
library functions that operates upon decSingle as member functions
|
||||
with the same name.
|
||||
decimal32 is a 32-bit decimal floating-point representation which
|
||||
provides 7 decimal digits of precision in a compressed format.
|
||||
decSingle module provides the functions for the decimal32 format;
|
||||
this format is intended for storage and interchange only and so
|
||||
the module provides utilities and conversions but no arithmetic functions.
|
||||
*/
|
||||
class QDECIMAL_EXPORT QDecSingle
|
||||
{
|
||||
// MEMBERS
|
||||
//! Embedded decSingle structure
|
||||
decSingle m_data;
|
||||
|
||||
public:
|
||||
// TYPES
|
||||
typedef decSingle* decSinglePtr_t;
|
||||
enum {
|
||||
MaxStrSize = QDECMAXSTRSIZE
|
||||
};
|
||||
|
||||
|
||||
// CREATORS
|
||||
//! Default constructor
|
||||
QDecSingle() { decSingleZero(&m_data); }
|
||||
|
||||
// Default Dtor and Copy Ctor are ok
|
||||
|
||||
// Constructors using decSingle structure
|
||||
QDecSingle(decSingle d) : m_data(d) {}
|
||||
QDecSingle(const decSingle* p) : m_data(*p) {}
|
||||
|
||||
// Conversion constructors using simple types
|
||||
QDecSingle(const char* str) { fromString(str); }
|
||||
QDecSingle(double d) { fromDouble(d); }
|
||||
|
||||
// Conversion constructors using composite types
|
||||
QDecSingle(const QDecDouble& d) { fromQDecDouble(d); }
|
||||
QDecSingle(const QDecPacked& p) { fromQDecPacked(p); }
|
||||
QDecSingle(const QDecNumber& n) { fromQDecNumber(n); }
|
||||
|
||||
//! Copy assignment
|
||||
QDecSingle& operator=(const QDecSingle& o)
|
||||
{ if(this != &o) m_data = o.m_data; return *this; }
|
||||
|
||||
//! Conversion operator to decSingle*
|
||||
operator decSinglePtr_t() { return &m_data; }
|
||||
|
||||
|
||||
// ACCESSORS
|
||||
const decSingle* data() const
|
||||
{ return &m_data; }
|
||||
|
||||
// MODIFIERS
|
||||
decSingle* data()
|
||||
{ return &m_data; }
|
||||
|
||||
|
||||
// UTILITIES & CONVERSIONS
|
||||
QDecSingle& fromBCD(int32_t exp, const QByteArray& bcd, int32_t sign) {
|
||||
decSingleFromBCD(&m_data, exp, (const uint8_t*)bcd.data(), sign);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecSingle& fromDouble(double d);
|
||||
|
||||
QDecSingle& fromPacked(int32_t exp, const QByteArray& pack) {
|
||||
decSingleFromPacked(&m_data, exp, (const uint8_t*)pack.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecSingle& fromPackedChecked(int32_t exp, const QByteArray& pack) {
|
||||
decSingleFromPackedChecked(&m_data, exp, (const uint8_t*)pack.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecSingle& fromString(const char* str, QDecContext* c = 0) {
|
||||
decSingleFromString(&m_data, str, CXT(c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Hexadecimal string in network byte order
|
||||
QDecSingle& fromHexString(const char* str);
|
||||
|
||||
QDecSingle& fromQDecDouble(const QDecDouble& d, QDecContext* c = 0)
|
||||
{ return fromWider(d,c); }
|
||||
|
||||
QDecSingle& fromQDecNumber(const QDecNumber& n, QDecContext* c = 0);
|
||||
|
||||
QDecSingle& fromQDecPacked(const QDecPacked& p);
|
||||
|
||||
QDecSingle& fromWider(const QDecDouble& d, QDecContext* c = 0);
|
||||
|
||||
int32_t getCoefficient(QByteArray& bcd) const {
|
||||
bcd.resize(DECSINGLE_Pmax);
|
||||
return decSingleGetCoefficient(&m_data, (uint8_t*)bcd.data());
|
||||
}
|
||||
|
||||
int32_t getExponent() const
|
||||
{ return decSingleGetExponent(&m_data); }
|
||||
|
||||
QDecSingle& setCoefficient(const QByteArray& bcd, int32_t sign) {
|
||||
decSingleSetCoefficient(&m_data, (const uint8_t*)bcd.data(), sign);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDecSingle& setExponent(int32_t exp, QDecContext* c = 0 ) {
|
||||
decSingleSetExponent(&m_data, CXT(c), exp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int32_t toBCD(int32_t& exp, QByteArray& bcd) {
|
||||
bcd.resize(DECSINGLE_Pmax);
|
||||
return decSingleToBCD(&m_data, &exp, (uint8_t*)bcd.data());
|
||||
}
|
||||
|
||||
double toDouble() const;
|
||||
|
||||
QByteArray toEngString() const {
|
||||
char str[MaxStrSize] = { 0 };
|
||||
return decSingleToEngString(&m_data, str);
|
||||
}
|
||||
|
||||
QByteArray toString() const {
|
||||
char str[MaxStrSize] = { 0 };
|
||||
return decSingleToString(&m_data, str);
|
||||
}
|
||||
|
||||
int32_t toPacked(int32_t& exp, QByteArray& pack) {
|
||||
pack.resize(DECSINGLE_Pmax);
|
||||
return decSingleToPacked(&m_data, &exp, (uint8_t*)pack.data());
|
||||
}
|
||||
|
||||
QDecDouble toQDecDouble() const;
|
||||
|
||||
QDecPacked toQDecPacked() const;
|
||||
|
||||
QDecNumber toQDecNumber() const;
|
||||
|
||||
QDecDouble toWider() const;
|
||||
|
||||
QDecSingle& zero()
|
||||
{ decSingleZero(&m_data); return *this; }
|
||||
|
||||
|
||||
// ARITHMETIC
|
||||
// No arithmetic routines defines for QDecSingle
|
||||
|
||||
// NON-COMPUTATIONAL
|
||||
|
||||
uint32_t radix() const
|
||||
{ return decSingleRadix(&m_data); }
|
||||
|
||||
const char* version() const
|
||||
{ return decSingleVersion(); }
|
||||
|
||||
|
||||
}; // end class
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(QDecSingle);
|
||||
|
||||
|
||||
QDECIMAL_EXPORT
|
||||
QTextStream& operator<<(QTextStream& ts, const QDecSingle& d);
|
||||
|
||||
|
||||
#endif /* Include guard */
|
||||
@@ -0,0 +1,7 @@
|
||||
Import('*')
|
||||
|
||||
env.AppendUnique(CPPPATH = ['#/decnumber'])
|
||||
|
||||
lib = env.Library('qdecimal', Glob('*.cc'))
|
||||
|
||||
env['PRJ_LIBS']['qdecimal'] = lib
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
include(../common.pri)
|
||||
|
||||
QT -= gui
|
||||
TEMPLATE = lib
|
||||
|
||||
# Pick if the library will be static or dynamic:
|
||||
CONFIG += static
|
||||
# or dynamic (don't forget to define QDECIMAL_SHARED
|
||||
#CONFIG += shared
|
||||
#DEFINES += QDECIMAL_SHARED=2
|
||||
# 1=import, client app, 2=export, source shared library (here)
|
||||
|
||||
|
||||
TARGET = qdecimal
|
||||
DEPENDPATH += .
|
||||
# To include decnumber headers
|
||||
INCLUDEPATH += ../decnumber
|
||||
DESTDIR = ../lib
|
||||
LIBS += -L../lib -ldecnumber
|
||||
|
||||
# Input
|
||||
HEADERS += QDecContext.hh \
|
||||
QDecDouble.hh \
|
||||
QDecPacked.hh \
|
||||
QDecNumber.hh \
|
||||
QDecSingle.hh \
|
||||
QDecQuad.hh
|
||||
|
||||
SOURCES += QDecContext.cc \
|
||||
QDecDouble.cc \
|
||||
QDecPacked.cc \
|
||||
QDecNumber.cc \
|
||||
QDecSingle.cc \
|
||||
QDecQuad.cc
|
||||
Reference in New Issue
Block a user