|
|
|
// -*- c-basic-offset: 2 -*-
|
|
|
|
/* This file is part of the KDE libraries
|
|
|
|
Copyright (C) 2005 Klaus Niederkrueger <kniederk@math.uni-koeln.de>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
#ifndef _KNUMBER_H
|
|
|
|
#define _KNUMBER_H
|
|
|
|
|
|
|
|
#include <tdelibs_export.h>
|
|
|
|
|
|
|
|
#include "knumber_priv.h"
|
|
|
|
|
|
|
|
class TQString;
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @short Class that provides arbitrary precision numbers
|
|
|
|
*
|
|
|
|
* KNumber provides access to arbitrary precision numbers from within
|
|
|
|
* KDE.
|
|
|
|
*
|
|
|
|
* KNumber is based on the GMP (GNU Multiprecision) library and
|
|
|
|
* provides transparent support to integer, fractional and floating
|
|
|
|
* point number. It contains rudimentary error handling, and also
|
|
|
|
* includes methods for converting the numbers to TQStrings for
|
|
|
|
* output, and to read TQStrings to obtain a KNumber.
|
|
|
|
*
|
|
|
|
* The different types of numbers that can be represented by objects
|
|
|
|
* of this class will be described below:
|
|
|
|
*
|
|
|
|
* @li @p NumType::SpecialType - This type represents an error that
|
|
|
|
* has occurred, e.g. trying to divide 1 by 0 gives an object that
|
|
|
|
* represents infinity.
|
|
|
|
*
|
|
|
|
* @li @p NumType::IntegerType - The number is an integer. It can be
|
|
|
|
* arbitrarily large (restricted by the memory of the system).
|
|
|
|
*
|
|
|
|
* @li @p NumType::FractionType - A fraction is a number of the form
|
|
|
|
* denominator divided by nominator, where both denominator and
|
|
|
|
* nominator are integers of arbitrary size.
|
|
|
|
*
|
|
|
|
* @li @p NumType::FloatType - The number is of floating point
|
|
|
|
* type. These numbers are usually rounded, so that they do not
|
|
|
|
* represent precise values.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @author Klaus Niederkrueger <kniederk@math.uni-koeln.de>
|
|
|
|
*/
|
|
|
|
class KDE_EXPORT KNumber
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static KNumber const Zero;
|
|
|
|
static KNumber const One;
|
|
|
|
static KNumber const MinusOne;
|
|
|
|
static KNumber const Pi;
|
|
|
|
static KNumber const Euler;
|
|
|
|
static KNumber const NotDefined;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* KNumber tries to provide transparent access to the following type
|
|
|
|
* of numbers:
|
|
|
|
*
|
|
|
|
* @li @p NumType::SpecialType - Some type of error has occurred,
|
|
|
|
* further inspection with @p KNumber::ErrorType
|
|
|
|
*
|
|
|
|
* @li @p NumType::IntegerType - the number is an integer
|
|
|
|
*
|
|
|
|
* @li @p NumType::FractionType - the number is a fraction
|
|
|
|
*
|
|
|
|
* @li @p NumType::FloatType - the number is of floating point type
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
enum NumType {SpecialType, IntegerType, FractionType, FloatType};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A KNumber that represents an error, i.e. that is of type @p
|
|
|
|
* NumType::SpecialType can further distinguished:
|
|
|
|
*
|
|
|
|
* @li @p ErrorType::UndefinedNumber - This is e.g. the result of
|
|
|
|
* taking the square root of a negative number or computing
|
|
|
|
* \f$ \infty - \infty \f$.
|
|
|
|
*
|
|
|
|
* @li @p ErrorType::Infinity - Such a number can be e.g. obtained
|
|
|
|
* by dividing 1 by 0. Some further calculations are still allowed,
|
|
|
|
* e.g. \f$ \infty + 5 \f$ still gives \f$\infty\f$.
|
|
|
|
*
|
|
|
|
* @li @p ErrorType::MinusInfinity - MinusInfinity behaves similarly
|
|
|
|
* to infinity above. It can be obtained by changing the sign of
|
|
|
|
* infinity.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
enum ErrorType {UndefinedNumber, Infinity, MinusInfinity};
|
|
|
|
|
|
|
|
KNumber(signed int num = 0);
|
|
|
|
KNumber(unsigned int num);
|
|
|
|
KNumber(signed long int num);
|
|
|
|
KNumber(unsigned long int num);
|
|
|
|
KNumber(unsigned long long int num);
|
|
|
|
|
|
|
|
KNumber(double num);
|
|
|
|
|
|
|
|
KNumber(KNumber const & num);
|
|
|
|
|
|
|
|
KNumber(TQString const & num);
|
|
|
|
|
|
|
|
~KNumber()
|
|
|
|
{
|
|
|
|
delete _num;
|
|
|
|
}
|
|
|
|
|
|
|
|
KNumber const & operator=(KNumber const & num);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the type of the number, as explained in @p KNumber::NumType.
|
|
|
|
*/
|
|
|
|
NumType type(void) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set whether the output of numbers (with KNumber::toTQString)
|
|
|
|
* should happen as floating point numbers or not. This method has
|
|
|
|
* in fact only an effect on numbers of type @p
|
|
|
|
* NumType::FractionType, which can be either displayed as fractions
|
|
|
|
* or in decimal notation.
|
|
|
|
*
|
|
|
|
* The default behavior is not to display fractions in floating
|
|
|
|
* point notation.
|
|
|
|
*/
|
|
|
|
static void setDefaultFloatOutput(bool flag);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set whether a number constructed from a TQString should be
|
|
|
|
* initialized as a fraction or as a float, e.g. "1.01" would be
|
|
|
|
* treated as 101/100, if this flag is set to true.
|
|
|
|
*
|
|
|
|
* The default setting is false.
|
|
|
|
*/
|
|
|
|
static void setDefaultFractionalInput(bool flag);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the default precision to be *at least* @p prec (decimal)
|
|
|
|
* digits. All subsequent initialized floats will use at least this
|
|
|
|
* precision, but previously initialized variables are unaffected.
|
|
|
|
*/
|
|
|
|
static void setDefaultFloatPrecision(unsigned int prec);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* What a terrible method name!! When displaying a fraction, the
|
|
|
|
* default mode gives @p "nomin/denom". With this method one can
|
|
|
|
* choose to display a fraction as @p "integer nomin/denom".
|
|
|
|
*
|
|
|
|
* Examples: Default representation mode is 47/17, but if @p flag is
|
|
|
|
* @p true, then the result is 2 13/17.
|
|
|
|
*/
|
|
|
|
static void setSplitoffIntegerForFractionOutput(bool flag);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a TQString representing the KNumber.
|
|
|
|
*
|
|
|
|
* @param width This number specifies the maximal length of the
|
|
|
|
* output, before the method switches to exponential notation and
|
|
|
|
* does rounding. For negative numbers, this option is ignored.
|
|
|
|
*
|
|
|
|
* @param prec This parameter controls the number of digits
|
|
|
|
* following the decimal point. For negative numbers, this option
|
|
|
|
* is ignored.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
TQString const toTQString(int width = -1, int prec = -1) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compute the absolute value, i.e. @p x.abs() returns the value
|
|
|
|
*
|
|
|
|
* \f[ \left\{\begin{array}{cl} x, & x \ge 0 \\ -x, & x <
|
|
|
|
* 0\end{array}\right.\f]
|
|
|
|
* This method works for \f$ x = \infty \f$ and \f$ x = -\infty \f$.
|
|
|
|
*/
|
|
|
|
KNumber const abs(void) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compute the square root. If \f$ x < 0 \f$ (including \f$
|
|
|
|
* x=-\infty \f$), then @p x.sqrt() returns @p
|
|
|
|
* ErrorType::UndefinedNumber.
|
|
|
|
*
|
|
|
|
* If @p x is an integer or a fraction, then @p x.sqrt() tries to
|
|
|
|
* compute the exact square root. If the square root is not a
|
|
|
|
* fraction, then a float with the default precision is returned.
|
|
|
|
*
|
|
|
|
* This method works for \f$ x = \infty \f$ giving \f$ \infty \f$.
|
|
|
|
*/
|
|
|
|
KNumber const sqrt(void) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compute the cube root.
|
|
|
|
*
|
|
|
|
* If @p x is an integer or a fraction, then @p x.cbrt() tries to
|
|
|
|
* compute the exact cube root. If the cube root is not a fraction,
|
|
|
|
* then a float is returned, but
|
|
|
|
*
|
|
|
|
* WARNING: A float cube root is computed as a standard @p double
|
|
|
|
* that is later transformed back into a @p KNumber.
|
|
|
|
*
|
|
|
|
* This method works for \f$ x = \infty \f$ giving \f$ \infty \f$,
|
|
|
|
* and for \f$ x = -\infty \f$ giving \f$ -\infty \f$.
|
|
|
|
*/
|
|
|
|
KNumber const cbrt(void) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Truncates a @p KNumber to its integer type returning a number of
|
|
|
|
* type @p NumType::IntegerType.
|
|
|
|
*
|
|
|
|
* If \f$ x = \pm\infty \f$, integerPart leaves the value unchanged,
|
|
|
|
* i.e. it returns \f$ \pm\infty \f$.
|
|
|
|
*/
|
|
|
|
KNumber const integerPart(void) const;
|
|
|
|
|
|
|
|
KNumber const power(KNumber const &exp) const;
|
|
|
|
|
|
|
|
KNumber const operator+(KNumber const & arg2) const;
|
|
|
|
KNumber const operator -(void) const;
|
|
|
|
KNumber const operator-(KNumber const & arg2) const;
|
|
|
|
KNumber const operator*(KNumber const & arg2) const;
|
|
|
|
KNumber const operator/(KNumber const & arg2) const;
|
|
|
|
KNumber const operator%(KNumber const & arg2) const;
|
|
|
|
|
|
|
|
KNumber const operator&(KNumber const & arg2) const;
|
|
|
|
KNumber const operator|(KNumber const & arg2) const;
|
|
|
|
KNumber const operator<<(KNumber const & arg2) const;
|
|
|
|
KNumber const operator>>(KNumber const & arg2) const;
|
|
|
|
|
|
|
|
operator bool(void) const;
|
|
|
|
operator signed long int(void) const;
|
|
|
|
operator unsigned long int(void) const;
|
|
|
|
operator unsigned long long int(void) const;
|
|
|
|
operator double(void) const;
|
|
|
|
|
|
|
|
bool const operator==(KNumber const & arg2) const
|
|
|
|
{ return (compare(arg2) == 0); }
|
|
|
|
|
|
|
|
bool const operator!=(KNumber const & arg2) const
|
|
|
|
{ return (compare(arg2) != 0); }
|
|
|
|
|
|
|
|
bool const operator>(KNumber const & arg2) const
|
|
|
|
{ return (compare(arg2) > 0); }
|
|
|
|
|
|
|
|
bool const operator<(KNumber const & arg2) const
|
|
|
|
{ return (compare(arg2) < 0); }
|
|
|
|
|
|
|
|
bool const operator>=(KNumber const & arg2) const
|
|
|
|
{ return (compare(arg2) >= 0); }
|
|
|
|
|
|
|
|
bool const operator<=(KNumber const & arg2) const
|
|
|
|
{ return (compare(arg2) <= 0); }
|
|
|
|
|
|
|
|
KNumber & operator +=(KNumber const &arg);
|
|
|
|
KNumber & operator -=(KNumber const &arg);
|
|
|
|
|
|
|
|
|
|
|
|
//KNumber const toFloat(void) const;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
void simplifyRational(void);
|
|
|
|
int const compare(KNumber const & arg2) const;
|
|
|
|
|
|
|
|
_knumber *_num;
|
|
|
|
static bool _float_output;
|
|
|
|
static bool _fraction_input;
|
|
|
|
static bool _splitoffinteger_output;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif // _KNUMBER_H
|