service plugin and qdecimal library has been added

This commit is contained in:
Zdenek Jonak
2016-02-09 21:55:05 +01:00
parent 3d68281c87
commit 4d74bed177
251 changed files with 127772 additions and 1 deletions
+131
View File
@@ -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;
}
+251
View File
@@ -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 */
+116
View File
@@ -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;
}
+454
View File
@@ -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 */
+79
View File
@@ -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 */
+67
View File
@@ -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;
}
+433
View File
@@ -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 */
+83
View File
@@ -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();
}
+108
View File
@@ -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 */
+100
View File
@@ -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;
}
+442
View File
@@ -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 */
+102
View File
@@ -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;
}
+200
View File
@@ -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 */
+7
View File
@@ -0,0 +1,7 @@
Import('*')
env.AppendUnique(CPPPATH = ['#/decnumber'])
lib = env.Library('qdecimal', Glob('*.cc'))
env['PRJ_LIBS']['qdecimal'] = lib
+37
View File
@@ -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