| /******************************************************************************* |
| * Copyright (c) 2016 CEA LIST. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Created on: 10 mai 2016 |
| * |
| * Contributors: |
| * Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr |
| * - Initial API and Implementation |
| ******************************************************************************/ |
| |
| #ifndef FML_NUMERIC_GMP_FLOATIMPL_H_ |
| #define FML_NUMERIC_GMP_FLOATIMPL_H_ |
| |
| #include <gmpxx.h> |
| |
| #include <fml/numeric/Number.h> |
| |
| #include <fml/numeric/Integer.h> |
| #include <fml/numeric/Rational.h> |
| |
| |
| namespace sep |
| { |
| |
| |
| class Float : |
| public Number, |
| public GenericNumberClass< mpf_class , Float > |
| { |
| |
| AVM_DECLARE_CLONABLE_CLASS( Float ) |
| |
| |
| /** |
| * TYPEDEF |
| */ |
| public: |
| typedef mpf_class RawValueType; |
| |
| private: |
| typedef GenericNumberClass< RawValueType , Float > ThisNumberClass; |
| |
| |
| public: |
| /** |
| * CONSTRUCTOR |
| * Default |
| */ |
| // RawValueType |
| Float(const RawValueType & aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( aValue ) ) |
| { |
| //!! NOTHING |
| } |
| |
| // mpq_class |
| Float(const mpq_class & aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( aValue ) ) |
| { |
| //!! NOTHING |
| } |
| |
| // mpq_t |
| Float(const mpq_t & aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( mpq_class(aValue) ) ) |
| { |
| //!! NOTHING |
| } |
| |
| |
| // mpz_class |
| Float(const mpz_class & aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType(aValue) ) |
| { |
| //!! NOTHING |
| } |
| |
| // mpz_t |
| Float(const mpz_t & aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( mpz_class(aValue) ) ) |
| { |
| //!! NOTHING |
| } |
| |
| // Rational |
| Float(const Rational & aRational) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( aRational.getValue() ) ) |
| //ThisNumberClass( RawValueType( static_cast<sep::BasicRational>(aRational).getValue() ) ) |
| //ThisNumberClass( RawValueType( reinterpret_cast<__gmp_expr>(aRational).getValue() ) ) |
| //ThisNumberClass( RawValueType( reinterpret_cast<GenericNumberClass>(aRational).getValue() ) ) |
| //ThisNumberClass( RawValueType( reinterpret_cast<GenericNumberClass<mpq_class , Rational>>(aRational).getValue() ) ) |
| { |
| //!! NOTHING |
| } |
| |
| // Integer |
| Float(const Integer & anInteger) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( anInteger.getValue() ) ) |
| //ThisNumberClass( RawValueType( reinterpret_cast<GenericNumberClass>(anInteger).getValue() ) ) |
| //ThisNumberClass( RawValueType( reinterpret_cast<GenericNumberClass<mpz_class , Integer>>(anInteger).getValue() ) ) |
| { |
| //!! NOTHING |
| } |
| |
| // avm_float_t |
| Float(avm_float_t aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType(aValue) ) |
| { |
| //!! NOTHING |
| } |
| |
| #ifdef _AVM_NEED_INT64_T_OVERLOADS_ |
| |
| // avm_integer_t i.e. avm_int64_t |
| Float(avm_integer_t aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( static_cast< long >(aValue) ) ) |
| { |
| //!! NOTHING |
| } |
| |
| // avm_uinteger_t i.e. avm_uint64_t |
| Float(avm_uinteger_t aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( static_cast< unsigned long >(aValue) ) ) |
| { |
| //!! NOTHING |
| } |
| |
| // long |
| Float(long aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( aValue ) ) |
| { |
| //!! NOTHING |
| } |
| |
| Float(unsigned long aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType( aValue ) ) |
| { |
| //!! NOTHING |
| } |
| |
| #else |
| |
| // avm_integer_t i.e. avm_int64_t |
| Float(avm_integer_t aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType(aValue) ) |
| { |
| //!! NOTHING |
| } |
| |
| // avm_uinteger_t i.e. avm_uint64_t |
| Float(avm_uinteger_t aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType(aValue) ) |
| { |
| //!! NOTHING |
| } |
| |
| #endif /* _AVM_NEED_INT64_T_OVERLOADS_ */ |
| |
| // int32_t |
| Float(int aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType(aValue) ) |
| { |
| //!! NOTHING |
| } |
| |
| // uint32_t |
| Float(unsigned int aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType(aValue) ) |
| { |
| //!! NOTHING |
| } |
| |
| // std::string |
| Float(const std::string & aValue) |
| : Number( CLASS_KIND_T( Float ) ), |
| ThisNumberClass( RawValueType(aValue) ) |
| { |
| //!! NOTHING |
| } |
| |
| /** |
| * CONSTRUCTOR |
| * Copy |
| */ |
| Float(const Float & aFloat) |
| : Number( aFloat ), |
| ThisNumberClass( aFloat ) |
| { |
| //!! NOTHING |
| } |
| |
| /** |
| * DESTRUCTOR |
| */ |
| virtual ~Float() |
| { |
| //!! NOTHING |
| } |
| |
| |
| /** |
| * BASICS TESTS |
| */ |
| virtual inline int sign() const |
| { |
| return( mpf_sgn(ThisNumberClass::mValue.get_mpf_t()) ); |
| } |
| |
| virtual inline bool isZero() const |
| { |
| return( sign() == 0 ); |
| } |
| |
| virtual inline bool isOne() const |
| { |
| return( mpf_cmp_si(ThisNumberClass::mValue.get_mpf_t(), 1) == 0 ); |
| } |
| |
| virtual inline bool isNegativeOne() const |
| { |
| return( mpf_cmp_si(ThisNumberClass::mValue.get_mpf_t(), -1) == 0 ); |
| } |
| |
| |
| /** |
| * CONVERSION |
| */ |
| #define MPF_IS_INTEGER(MPF_VAL, INF, SUP) \ |
| (mpf_cmp_si(MPF_VAL.get_mpf_t(), MPF_VAL.get_si()) == 0) && \ |
| (mpf_cmp_si(MPF_VAL.get_mpf_t(), INF) >= 0) && \ |
| (mpf_cmp_ui(MPF_VAL.get_mpf_t(), SUP) <= 0) |
| |
| #define MPF_IS_POSITIVE_INTEGER(MPF_VAL, SUP) (sign() >= 0) && \ |
| (mpf_cmp_ui(MPF_VAL.get_mpf_t(), MPF_VAL.get_ui()) == 0) && \ |
| (mpf_cmp_ui(MPF_VAL.get_mpf_t(), SUP) <= 0) |
| |
| |
| inline virtual bool isInt32() const |
| { |
| return( MPF_IS_INTEGER(ThisNumberClass::mValue, |
| AVM_NUMERIC_MIN_INT32, AVM_NUMERIC_MAX_INT32) ); |
| } |
| |
| inline virtual avm_int32_t toInt32() const |
| { |
| return( static_cast< avm_int32_t >( |
| ThisNumberClass::mValue.get_si() ) ); |
| } |
| |
| |
| inline virtual bool isInt64() const |
| { |
| return( MPF_IS_INTEGER(ThisNumberClass::mValue, |
| AVM_NUMERIC_MIN_INT64, AVM_NUMERIC_MAX_INT64) ); |
| } |
| |
| inline virtual avm_int64_t toInt64() const |
| { |
| return( static_cast< avm_int64_t >( |
| ThisNumberClass::mValue.get_si() ) ); |
| } |
| |
| |
| inline virtual bool isInteger() const |
| { |
| return( MPF_IS_INTEGER(ThisNumberClass::mValue, |
| AVM_NUMERIC_MIN_INTEGER, AVM_NUMERIC_MAX_INTEGER) ); |
| } |
| |
| inline virtual avm_integer_t toInteger() const |
| { |
| return( static_cast< avm_integer_t >( |
| ThisNumberClass::mValue.get_si() ) ); |
| } |
| |
| |
| inline virtual bool isPosInteger() const |
| { |
| return( MPF_IS_POSITIVE_INTEGER( |
| ThisNumberClass::mValue, AVM_NUMERIC_MAX_UINTEGER) ); |
| } |
| |
| |
| inline virtual bool isUInteger() const |
| { |
| return( MPF_IS_POSITIVE_INTEGER( |
| ThisNumberClass::mValue, AVM_NUMERIC_MAX_UINTEGER) ); |
| } |
| |
| inline virtual avm_uinteger_t toUInteger() const |
| { |
| return( static_cast< avm_uinteger_t >( |
| ThisNumberClass::mValue.get_ui() ) ); |
| } |
| |
| |
| inline virtual bool isRational() const |
| { |
| return( true ); |
| } |
| |
| virtual avm_integer_t toDenominator() const |
| { |
| return( static_cast< avm_integer_t >( |
| mpq_class(ThisNumberClass::mValue).get_den().get_si() ) ); |
| } |
| |
| virtual avm_integer_t toNumerator() const |
| { |
| return( static_cast< avm_integer_t >( |
| mpq_class(ThisNumberClass::mValue).get_num().get_si() ) ); |
| } |
| |
| |
| inline virtual bool isFloat() const |
| { |
| return( true ); |
| } |
| |
| inline virtual avm_float_t toFloat() const |
| { |
| return( static_cast< avm_float_t >( |
| ThisNumberClass::mValue.get_d() ) ); |
| } |
| |
| |
| inline virtual bool isReal() const |
| { |
| return( true ); |
| } |
| |
| inline virtual avm_real_t toReal() const |
| { |
| return( static_cast< avm_real_t >( |
| ThisNumberClass::mValue.get_d() ) ); |
| } |
| |
| |
| /** |
| * math function |
| */ |
| inline void set_pow(avm_uinteger_t anExponent) |
| { |
| RawValueType mpResult; |
| |
| mpf_pow_ui( mpResult.get_mpf_t(), |
| ThisNumberClass::mValue.get_mpf_t(), anExponent ); |
| |
| ThisNumberClass::mValue = mpResult; |
| } |
| |
| inline void set_pow(double aValue, avm_uinteger_t anExponent) |
| { |
| mpf_pow_ui( ThisNumberClass::mValue.get_mpf_t(), |
| RawValueType(aValue).get_mpf_t(), anExponent ); |
| } |
| |
| |
| /** |
| * Serialization |
| */ |
| virtual void toStream(OutStream & os) const |
| { |
| os << TAB << OS_FLOAT_PRECISION << mValue; |
| AVM_DEBUG_REF_COUNTER(os); |
| os << EOL_FLUSH; |
| } |
| |
| virtual std::string str() const |
| { |
| return( OSS() /*<< OS_REAL_PRECISION*/ << mValue ); |
| } |
| |
| inline virtual std::string strNum( |
| avm_uint8_t precision = AVM_MUMERIC_PRECISION) const |
| { |
| return( OSS() << std::fixed |
| << std::setprecision( precision ) << mValue ); |
| } |
| |
| }; |
| |
| |
| } /* namespace sep */ |
| |
| #endif /* FML_NUMERIC_GMP_FLOATIMPL_H_ */ |