⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gmpq_type.h

📁 很多二维 三维几何计算算法 C++ 类库
💻 H
字号:
// Copyright (c) 2002,2003  Utrecht University (The Netherlands),// ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg// (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),// and Tel-Aviv University (Israel).  All rights reserved.//// This file is part of CGAL (www.cgal.org); you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public License as// published by the Free Software Foundation; version 2.1 of the License.// See the file LICENSE.LGPL distributed with CGAL.//// Licensees holding a valid commercial license may use this file in// accordance with the commercial license agreement provided with the software.//// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.3-branch/Number_types/include/CGAL/GMP/Gmpq_type.h $// $Id: Gmpq_type.h 37955 2007-04-05 13:02:19Z spion $////// Author(s)     : Andreas Fabri, Sylvain Pion#ifndef CGAL_GMPQ_Type_H#define CGAL_GMPQ_Type_H#include <CGAL/basic.h>#include <CGAL/GMP/Gmpz_type.h>#include <gmp.h>#include <mpfr.h>#include <utility>#include <string>#include <boost/operators.hpp>#include <CGAL/Handle_for.h>#include <CGAL/Profile_counter.h>CGAL_BEGIN_NAMESPACE// TODO : add mixed operators with Gmpz.// Wrapper around mpq_t to get the destructor call mpq_clear.// Contrary to mpz_t, there are no mpq_init_set_* functions,// so we simply call mpq_init() here.struct Gmpq_rep{  mpq_t mpQ;  Gmpq_rep()  { mpq_init(mpQ); }  ~Gmpq_rep() { mpq_clear(mpQ); }private:  // Make sure it does not get accidentally copied.  Gmpq_rep(const Gmpq_rep &);  Gmpq_rep & operator= (const Gmpq_rep &);};class Gmpq  : Handle_for<Gmpq_rep>,    boost::ordered_field_operators1< Gmpq  , boost::ordered_field_operators2< Gmpq, int    > >{  typedef Handle_for<Gmpq_rep> Base;public:  typedef Tag_false  Has_gcd;  typedef Tag_true   Has_division;  typedef Tag_false  Has_sqrt;  typedef Tag_true   Has_exact_ring_operations;  typedef Tag_true   Has_exact_division;  typedef Tag_false  Has_exact_sqrt;  Gmpq() {}  Gmpq(const mpq_t q)  { mpq_set(mpq(), q); }  Gmpq(int n)  { mpq_set_si(mpq(), n, 1); }  Gmpq(long n)  { mpq_set_si(mpq(), n, 1); }  Gmpq(unsigned long n)  { mpq_set_ui(mpq(), n, 1); }  Gmpq(const Gmpz& n)  { mpq_set_z(mpq(), n.mpz()); }  Gmpq(int n, int d)  {    if (d < 0) {      n = -n;      d = -d;    }    mpq_set_si(mpq(), n, d);    mpq_canonicalize(mpq());  }  Gmpq(signed long n, unsigned long d)  {    mpq_set_si(mpq(), n, d);    mpq_canonicalize(mpq());  }  Gmpq(unsigned long n, unsigned long d)  {    mpq_set_ui(mpq(), n, d);    mpq_canonicalize(mpq());  }  Gmpq(const Gmpz& n, const Gmpz& d)  {    mpz_set(mpq_numref(mpq()), n.mpz());    mpz_set(mpq_denref(mpq()), d.mpz());    mpq_canonicalize(mpq());  }  Gmpq(double d)  { mpq_set_d(mpq(), d); }  Gmpq(const std::string& str, int base = 10)  {    mpq_set_str(mpq(), str.c_str(), base);    mpq_canonicalize(mpq());  }#ifdef CGAL_ROOT_OF_2_ENABLE_HISTOGRAM_OF_NUMBER_OF_DIGIT_ON_THE_COMPLEX_CONSTRUCTOR  int tam() const { return 0; }  // put here a code                                 // measuring the number of digits                                 // of the Gmpq// a possible code is://  int tam() const { return std::max(numerator().tam(),//  	                                denominator().tam()); }// the same as Quotient<MP_Float>#endif  // Gives the memory size in bytes. (not documented yet)  std::size_t size() const  {    std::size_t s_num = mpz_size(mpq_numref(mpq())) * (mp_bits_per_limb/8);    std::size_t s_den = mpz_size(mpq_denref(mpq())) * (mp_bits_per_limb/8);    return s_num + s_den;  }  Gmpz numerator() const  { return Gmpz(mpq_numref(mpq())); }  Gmpz denominator() const  { return Gmpz(mpq_denref(mpq())); }  Gmpq operator+() const;  Gmpq operator-() const;  Gmpq& operator+=(const Gmpq &z);  Gmpq& operator-=(const Gmpq &z);  Gmpq& operator*=(const Gmpq &z);  Gmpq& operator/=(const Gmpq &z);  double to_double() const;  Sign sign() const;  const mpq_t & mpq() const { return Ptr()->mpQ; }  mpq_t & mpq() { return ptr()->mpQ; }  ~Gmpq()  {     CGAL_HISTOGRAM_PROFILER("[Gmpq sizes in log2 scale]",                             (unsigned) ( ::log(double(size())) / ::log(double(2)) )  );  }};inlinebooloperator==(const Gmpq &a, const Gmpq &b){ return mpq_equal(a.mpq(), b.mpq()); }inlinebooloperator<(const Gmpq &a, const Gmpq &b){ return mpq_cmp(a.mpq(), b.mpq()) < 0; }// mixed operators.inlinebooloperator<(const Gmpq &a, int b){ return mpq_cmp_si(a.mpq(), b, 1) < 0; }inlinebooloperator>(const Gmpq &a, int b){ return mpq_cmp_si(a.mpq(), b, 1) > 0; }inlinebooloperator==(const Gmpq &a, int b){ return mpq_cmp_si(a.mpq(), b, 1) == 0; }inlineGmpqGmpq::operator-() const{    Gmpq Res;    mpq_neg(Res.mpq(), mpq());    return Res;}inlineGmpqGmpq::operator+() const{  return Gmpq(mpq());}inlineGmpq&Gmpq::operator+=(const Gmpq &z){    Gmpq Res;    mpq_add(Res.mpq(), mpq(), z.mpq());    swap(Res);    return *this;}inlineGmpq&Gmpq::operator-=(const Gmpq &z){    Gmpq Res;    mpq_sub(Res.mpq(), mpq(), z.mpq());    swap(Res);    return *this;}inlineGmpq&Gmpq::operator*=(const Gmpq &z){    Gmpq Res;    mpq_mul(Res.mpq(), mpq(), z.mpq());    swap(Res);    return *this;}inlineGmpq&Gmpq::operator/=(const Gmpq &z){    CGAL_precondition(z != 0);    Gmpq Res;    mpq_div(Res.mpq(), mpq(), z.mpq());    swap(Res);    return *this;}inlinedoubleGmpq::to_double() const{ return mpq_get_d(mpq()); }inlineSignGmpq::sign() const{ return static_cast<Sign>(mpq_sgn(mpq())); }inlinestd::ostream&operator<<(std::ostream& os, const Gmpq &z){  os << z.numerator() << "/" << z.denominator();  return os;}// inline// std::istream&// operator>>(std::istream& is, Gmpq &z)// {//   char c;//   Gmpz n, d;//   is >> n;//   is >> c;//   //CGAL_assertion(!is || c == '/');//   if (c != '/'){//     is.setstate(std::ios_base::failbit);//     return is;//   }//   is >> d;//   if (!is.fail()) {//     z = Gmpq(n,d);//   }//   return is;// }namespace Gmpq_detail {  inline  bool is_space (const std::istream& /*is*/, std::istream::int_type c)  {    std::istream::char_type cc= c;    return      (c == std::istream::traits_type::eof()) ||#ifndef CGAL_CFG_NO_LOCALE      std::isspace(cc, std::locale::classic() )#else      std::isspace(cc)#endif      ;  }  inline  bool is_eof (const std::istream& /*is*/, std::istream::int_type c)  {    return c == std::istream::traits_type::eof();  }  inline  bool is_digit (const std::istream& /*is*/, std::istream::int_type c)  {    std::istream::char_type cc= c;    return#ifndef CGAL_CFG_NO_LOCALE      std::isdigit(cc, std::locale::classic() )#else      std::isdigit(cc)#endif      ;  }}inlinestd::istream&operator>>(std::istream& is, Gmpq &z){  // reads rational and floating point literals.  const std::istream::char_type zero = '0';  std::istream::int_type c;  std::ios::fmtflags old_flags = is.flags();  is.unsetf(std::ios::skipws);  gmpz_eat_white_space(is);  Gmpz n(0);             // unsigned number before '/' or '.'  Gmpz d(1);             // number after '/', or denominator (fp-case)  bool negative = false; // do we have a leading '-'?  bool digits = false;   // for fp-case: are there any digits at all?  c = is.peek();  if (c != '.') {    // is there a sign?    if (c == '-' || c == '+') {      is.get();      negative = (c == '-');      gmpz_eat_white_space(is);      c=is.peek();    }    // read n (could be empty)    while (!Gmpq_detail::is_eof(is, c) && Gmpq_detail::is_digit(is, c)) {      digits = true;      n = n*10 + (c-zero);      is.get();      c = is.peek();    }    // are we done?    if (Gmpq_detail::is_eof(is, c) || Gmpq_detail::is_space(is, c)) {      is.flags(old_flags);      if (digits && !is.fail())	z = negative? Gmpq(-n,1): Gmpq(n,1);      return is;    }  } else    n = 0;  // now we have read n, we are not done, and c is the next character  // in the stream  if (c == '/' || c == '.') {    is.get();    if (c == '/') {      // rational case      is >> d;      is.flags(old_flags);      if (!is.fail())	z = negative? Gmpq(-n,d): Gmpq(n,d);      return is;    }    // floating point case; read number after '.' (may be empty)    while (true) {      c = is.peek();      if (Gmpq_detail::is_eof(is, c) || !Gmpq_detail::is_digit(is, c))	break;      // now we have a digit      is.get();      digits = true;      d *= 10;      n = n*10 + (c-zero);    }  }  // now we have read all digits after '.', and c is the next character;  // read the exponential part (optional)  int e = 0;  if (c == 'e' || c == 'E') {    is.get();    is >> e;  }  // now construct the Gmpq  if (!digits) {    // illegal floating-point number    is.setstate(std::ios_base::failbit);    is.flags(old_flags);    return is;  }  // handle e  if (e > 0)    while (e--) n *= 10;  else    while (e++) d *= 10;  is.flags(old_flags);  if (!is.fail())    z = (negative ? Gmpq(-n,d) : Gmpq(n,d));  return is;}CGAL_END_NAMESPACE#endif // CGAL_GMPQ_Type_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -