/********************* */ /*! \file rational_cln_imp.h ** \verbatim ** Original author: Tim King ** Major contributors: Morgan Deters ** Minor contributors (to current version): Dejan Jovanovic ** This file is part of the CVC4 project. ** Copyright (c) 2009-2014 New York University and The University of Iowa ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** ** \brief Multiprecision rational constants; wraps a CLN multiprecision ** rational. ** ** Multiprecision rational constants; wraps a CLN multiprecision rational. **/ #include "cvc4_public.h" #ifndef __CVC4__RATIONAL_H #define __CVC4__RATIONAL_H #include #include #include #include #include #include #include #include #include #include #include #include #include "util/exception.h" #include "util/integer.h" namespace CVC4 { class CVC4_PUBLIC RationalFromDoubleException : public Exception { public: RationalFromDoubleException(double d) throw(); }; /** ** A multi-precision rational constant. ** This stores the rational as a pair of multi-precision integers, ** one for the numerator and one for the denominator. ** The number is always stored so that the gcd of the numerator and denominator ** is 1. (This is referred to as referred to as canonical form in GMP's ** literature.) A consequence is that that the numerator and denominator may be ** different than the values used to construct the Rational. ** ** NOTE: The correct way to create a Rational from an int is to use one of the ** int numerator/int denominator constructors with the denominator 1. Trying ** to construct a Rational with a single int, e.g., Rational(0), will put you ** in danger of invoking the char* constructor, from whence you will segfault. **/ class CVC4_PUBLIC Rational { private: /** * Stores the value of the rational is stored in a C++ GMP rational class. * Using this instead of mpq_t allows for easier destruction. */ cln::cl_RA d_value; /** * Constructs a Rational from a mpq_class object. * Does a deep copy. * Assumes that the value is in canonical form, and thus does not * have to call canonicalize() on the value. */ //Rational(const mpq_class& val) : d_value(val) { } Rational(const cln::cl_RA& val) : d_value(val) { } public: /** * Creates a rational from a decimal string (e.g., "1.5"). * * @param dec a string encoding a decimal number in the format * [0-9]*\.[0-9]* */ static Rational fromDecimal(const std::string& dec); /** Constructs a rational with the value 0/1. */ Rational() : d_value(0){ } /** * Constructs a Rational from a C string in a given base (defaults to 10). * Throws std::invalid_argument if the string is not a valid rational. * For more information about what is a valid rational string, * see GMP's documentation for mpq_set_str(). */ explicit Rational(const char* s, unsigned base = 10) throw (std::invalid_argument){ cln::cl_read_flags flags; flags.syntax = cln::syntax_rational; flags.lsyntax = cln::lsyntax_standard; flags.rational_base = base; try{ d_value = read_rational(flags, s, NULL, NULL); }catch(...){ std::stringstream ss; ss << "Rational() failed to parse value \"" <