BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Polynomial/internal/Simple_interval_root.h
Go to the documentation of this file.
00001 // Copyright (c) 2005  Stanford University (USA).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Kinetic_data_structures/include/CGAL/Polynomial/internal/Simple_interval_root.h $
00016 // $Id: Simple_interval_root.h 45637 2008-09-18 15:41:45Z hemmer $
00017 //
00018 //
00019 // Author(s)     : Daniel Russel <drussel@alumni.princeton.edu>
00020 
00021 #ifndef CGAL_POLYNOMIAL_SIMPLE_INTERVAL_ROOT_H
00022 #define CGAL_POLYNOMIAL_SIMPLE_INTERVAL_ROOT_H
00023 #include <CGAL/Polynomial/basic.h>
00024 #include <CGAL/Real_embeddable_traits.h>
00025 #include <vector>
00026 CGAL_POLYNOMIAL_BEGIN_INTERNAL_NAMESPACE;
00027 
00029 
00033 template <class Traits>
00034 class Simple_interval_root
00035 {
00036   typedef Simple_interval_root<Traits> This;
00037 
00038 
00039   typedef enum Fields {INVALID= 4,UP=1, INF=2} Type_fields;
00040   typedef unsigned char Type;
00041   typedef typename Traits::Function Polynomial;
00042   typedef typename Traits::FT NT;
00043 public:
00044   Simple_interval_root(){
00045     set_type(INVALID);
00046     CGAL_Polynomial_assertion(is_null());
00047   }
00048 
00049   Simple_interval_root(double nt): function_(0), interval_(nt,nt) {
00050     if (std::numeric_limits<double>::has_infinity && (nt == std::numeric_limits<double>::infinity()
00051                                                    || -nt == std::numeric_limits<double>::infinity())) {
00052       if (nt == std::numeric_limits<double>::infinity() ) {
00053         set_type(INF|UP);
00054       }
00055       else {
00056         set_type(INF);
00057       }
00058     } else {
00059       set_type(0);
00060       ii_= std::make_pair(NT(nt),NT(nt));
00061     }
00062     audit();
00063     compute_approximation();
00064   }
00065 
00066   Simple_interval_root(const Simple_interval_root<Traits> &o):ii_(o.ii_), type_(o.type_), 
00067                                                               function_(o.function_),
00068                                                               kernel_(o.kernel_), interval_(o.interval_)
00069 #ifndef NDEBUG
00070                                                              , approximation_(o.approximation_)
00071 #endif
00072   {
00073     
00074   }
00075 
00076   /*Simple_interval_root(Type t): type_(t) {
00077     audit();
00078     compute_approximation();
00079     };*/
00080 
00082   Simple_interval_root(const NT &nt): ii_(std::make_pair(nt,nt)), function_(0), interval_(0,-1) {
00083     set_type(0);
00084     audit();
00085     compute_approximation();
00086   }
00087 
00088 
00090   Simple_interval_root(const std::pair<NT,NT> &ii,
00091                        const Polynomial &sa,
00092                        Sign slb, Sign,
00093                        Traits k): ii_(ii), function_(sa),
00094                                   kernel_(k), interval_(0,-1){
00095     //CGAL_Polynomial_precondition(!ii_.is_singular());
00096     //Sign slb= sign_(ii_.lower_bound());
00097     if (slb == CGAL::NEGATIVE) {
00098       set_type(UP);
00099     } else {
00100       set_type(0);
00101     }
00102     compute_approximation();
00103     audit();
00104   }
00105 
00106   static This infinity() {
00107     static This ret(std::numeric_limits<double>::infinity());
00108     CGAL_Polynomial_postcondition(ret.is_infinite());
00109     //ret.compute_approximation();
00110     return ret;
00111   }
00112 
00113   bool operator<(const This &o) const
00114   {
00115     CGAL_Polynomial_expensive_precondition(!is_null() && !o.is_null());
00116     Comparison_result r= compare(o);
00117     audit(); o.audit();
00118     return r==SMALLER;
00119   }
00120 
00121   bool operator>(const This &o) const
00122   {
00123     CGAL_Polynomial_expensive_precondition(!is_null() && !o.is_null());
00124     Comparison_result r= compare(o);
00125     audit(); o.audit();
00126     return r==LARGER;
00127   }
00128 
00129   bool operator!=(const This &o) const
00130   {
00131     if (is_null()) return !o.is_null();
00132     else if (o.is_null()) return true;
00133     CGAL_Polynomial_expensive_precondition(!is_null() && !o.is_null());
00134     Comparison_result r= compare(o);
00135     audit(); o.audit();
00136     return r != EQUAL;
00137   }
00138   bool operator<=(const This &o) const
00139   {
00140     CGAL_Polynomial_expensive_precondition(!is_null() && !o.is_null());
00141     Comparison_result r= compare(o);
00142     audit(); o.audit();
00143     return r != LARGER;
00144   }
00145   bool operator>=(const This &o) const
00146   {
00147     CGAL_Polynomial_expensive_precondition(!is_null() && !o.is_null());
00148     Comparison_result r= compare(o);
00149     audit(); o.audit();
00150     return r != SMALLER;
00151   }
00152 
00153   bool operator==(const This &o) const
00154   {
00155     if (is_null()) return o.is_null();
00156     else if (o.is_null()) return false;
00157     CGAL_Polynomial_expensive_precondition(!is_null() && !o.is_null());
00158     Comparison_result r= compare(o);
00159     audit(); o.audit();
00160     return r==EQUAL;
00161   }
00162 
00163  
00164   const std::pair<NT, NT>& isolating_interval() const
00165   {
00166     CGAL_Polynomial_precondition(!is_infinite());
00167     CGAL_Polynomial_expensive_precondition(!is_null());
00168     return ii_;
00169   }
00170 
00172   void write(std::ostream &o) const
00173   {
00174 #ifndef NDEBUG
00175     This t=*this;
00176     t.write_internal(o);
00177 #else
00178     write_internal(o);
00179 #endif
00180   }
00181 
00182   void print() const
00183   {
00184     write(std::cout);
00185   }
00186 
00188   This operator-() const
00189   {
00190     CGAL_Polynomial_expensive_precondition(!is_null());
00191     if (is_pos_inf()) {
00192       This ret;
00193       ret.type_=INF;
00194       return ret;
00195     } else if (is_neg_inf()) return infinity();
00196     else {
00197       This copy= *this;
00198       copy.ii_= std::make_pair(-ii_.second, -ii_.first);
00199       typename Traits::Negate_variable nf= kernel_.negate_variable_object();
00200       copy.function_= nf(function_);
00201       if (type_&UP) {
00202         copy.type_= 0;
00203       } else {
00204         copy.type_=UP;
00205       }
00206       return copy;
00207     }
00208   }
00209 
00211   bool is_infinite() const
00212   {
00213     return type_&INF;
00214   }
00215  
00216   
00217   Comparison_result compare(const This &o) const
00218   {
00219     audit();
00220     o.audit();
00221     CGAL_Polynomial_precondition(-SMALLER == LARGER);
00222     if (is_infinite() || o.is_infinite()) {
00223       if (is_pos_inf() && o.is_pos_inf()) return EQUAL;
00224       if (is_neg_inf() && o.is_neg_inf()) return EQUAL;
00225       else if (is_pos_inf() || o.is_neg_inf()) return LARGER;
00226       else if (is_neg_inf() || o.is_pos_inf()) return SMALLER;
00227       else {
00228         CGAL_Polynomial_assertion(0); return EQUAL;
00229       }
00230     } else {
00231       CGAL::Comparison_result cmp;
00232       if (try_compare(o, cmp)) return cmp;
00233       else return compare_finite(o);
00234     }
00235   }
00236  std::pair<double, double> compute_interval(double accuracy=.0001) const
00237   {
00238     if (interval_.first > interval_.second) {
00239       //std::cout << "Computing interval for ";
00240       //write_raw(std::cout) << std::endl;
00241       std::pair<double,double> r= internal_compute_interval(accuracy);
00242       /*std::cout << "Got " << CGAL::to_interval(ii_.first).first << "..." 
00243         << CGAL::to_interval(ii_.second).second << std::endl;*/
00244       interval_=std::make_pair(CGAL::to_interval(ii_.first).first, CGAL::to_interval(ii_.second).second);
00245     } 
00246     return interval_;
00247   }
00248 
00249   double compute_double(double accuracy) const
00250   {
00251     if (is_infinite()) {
00252       if (is_up()) {
00253         return double_inf_rep();
00254       }
00255       else {
00256         return -double_inf_rep();
00257       }
00258     }
00259     //This t= *this;
00260     std::pair<double, double> i= compute_interval(accuracy);
00261     return (i.first+i.second)/2.0;
00262   }
00263 
00264 
00265   NT rational_between(const This &o) const {
00266     CGAL_precondition(CGAL::compare(*this,o) == CGAL::SMALLER);
00267     CGAL_precondition(ii_.first != ii_.second || ii_.second != o.ii_.first || o.ii_.first != o.ii_.second);
00268     compare(o);
00269     CGAL_precondition(ii_.first != ii_.second || ii_.second != o.ii_.first || o.ii_.first != o.ii_.second);
00270     //write_internal(std::cout) << std::endl;
00271     //write_internal(std::cout) << std::endl;
00272     if (is_neg_inf()) return o.ii_.first -1;
00273         
00274     // hopefully disjoint
00275     NT ret = ii_.second;
00276     NT step= NT(.0000000596046447753906250000000);
00277     
00278     do {
00279       while (This(ret) <= *this) {
00280         ret+= step;
00281       }
00282       while (This(ret) >= o) {
00283         ret -= step;
00284       }
00285       step= step/NT(2.0);
00286       /*std::cout << ret << "  (" << step << ")" 
00287                 << o.ii_.first - ii_.second 
00288                 << " " << o.ii_.second- ii_.first << std::endl;*/
00289     } while (This(ret) >= o || This(ret) <= *this);
00290     return ret;
00291   }
00292 
00293 protected:
00294   std::pair<double, double> internal_compute_interval(double accuracy) const
00295   {
00296  
00297     if (type_&INF) {
00298       if (is_up()) {
00299         return std::pair<double, double>(double_inf_rep(), double_inf_rep());
00300       }
00301       else {
00302         return std::pair<double, double>(-double_inf_rep(), -double_inf_rep());
00303       }
00304     }
00305 
00306     //double oaw;                           //= ii_.approximate_width();
00307     // int ct=0;
00308     while (ii_.second != ii_.first && ii_.second-ii_.first > NT(accuracy)) {
00309       refine();
00310       /*++ct;
00311       if (ct== 30) {
00312         std::cerr << "Error subdividing ";
00313         write_internal(std::cerr) << std::endl;
00314         break;
00315         }*/
00316     }
00317     return std::make_pair(CGAL::to_interval(ii_.first).first, CGAL::to_interval(ii_.second).second);
00318   }
00319   std::ostream& write_internal(std::ostream &o) const
00320   {
00321     if (is_pos_inf()) {
00322       o << "inf";
00323     }
00324     else if (is_neg_inf()) {
00325       o << "-inf";
00326     }
00327     else {
00328       if (ii_.first == ii_.second) {
00329         o << ii_.first;
00330       } else {
00331         o << function_ << " in [" << ii_.first << "," << ii_.second << "]";
00332         o << " = " << internal_compute_interval(.00001).first 
00333           << "..." << internal_compute_interval(.00001).second;
00334       }
00335     }
00336     return o;
00337   }
00338 
00339   std::ostream & write_raw(std::ostream &o) const
00340   {
00341     if (is_pos_inf()) {
00342       o << "inf";
00343     }
00344     else if (is_neg_inf()) {
00345       o << "-inf";
00346     }
00347     else {
00348       if (ii_.first == ii_.second) {
00349         o << ii_.first;
00350       } else {
00351         o << function_ << " in [" << ii_.first << "," << ii_.second << "]";
00352       }
00353     }
00354     return o;
00355   }
00356 
00357   void set_type(Type t)
00358   {
00359     type_=t;
00360   }
00361 
00362   bool is_pos_inf() const
00363   {
00364     return (type_&INF) && (type_&UP);
00365   }
00366 
00367   bool is_neg_inf() const
00368   {
00369     return (type_&INF) && !(type_&UP);
00370   }
00371 
00372   bool contains_root(Sign ls, Sign us) const
00373   {
00374     return (is_up() && ls==NEGATIVE && us==POSITIVE) || (is_down() && ls==POSITIVE && us==NEGATIVE);
00375   }
00376 
00377   void refine() const
00378   {
00379     if (ii_.first == ii_.second) return;
00380     //CGAL_Polynomial_precondition(!is_rational());
00381     //CGAL_Polynomial_precondition(is_normal());
00382     NT mp = (ii_.first + ii_.second)*NT(0.5);
00383     Sign sn= sign_at(mp);
00384     if (sn == ZERO) {
00385       ii_= std::make_pair(mp,mp);
00386     } else if (contains_root(lower_sign(), sn)) {
00387       ii_.second= mp;
00388     } else {
00389       ii_.first= mp;
00390     }
00391   }
00392 
00393   void refine_using(const std::pair<NT, NT> &o) const
00394   {
00395     if (ii_.first== ii_.second) return;
00396     std::vector<NT > plist;
00397     plist.push_back(ii_.first);
00398     if (o.first < ii_.second && o.first > ii_.first) {
00399       plist.push_back(o.first);
00400     }
00401     if (o.first != o.second && o.second < ii_.second && o.second > ii_.first) {
00402       plist.push_back(o.second);
00403     }
00404     plist.push_back(ii_.second);
00405 
00406     /*for (unsigned int i=0; i< plist.size(); ++i) {
00407       std::cout << plist[i] << "   ";
00408     }
00409     std::cout << std::endl;*/
00410 
00411     if (plist.size()==2) return;
00412     
00413     CGAL::Sign ps= lower_sign();
00414     //std::cout << "ps is " << ps << std::endl;
00415     CGAL_assertion(ps != CGAL::ZERO);
00416     for (unsigned int i=1; i< plist.size()-1; ++i) {
00417       CGAL::Sign sn= sign_at(plist[i]);
00418       //std::cout << "sn is " << ps << std::endl;
00419       if (sn==0) {
00420         ii_= std::make_pair(plist[i], plist[i]);
00421         audit();
00422         return;
00423       } else if (sn != ps) {
00424         ii_= std::make_pair(plist[i-1], plist[i]);
00425         audit();
00426         return;
00427       }
00428     }
00429 
00430     ii_= std::make_pair(plist[plist.size()-2], plist[plist.size()-1]);
00431     CGAL_postcondition(sign_at(plist[plist.size()-2]) == ps);
00432     CGAL_postcondition(sign_at(plist[plist.size()-1]) == -ps);
00433     audit();
00434   }
00435 
00436   Comparison_result compare_finite(const This &o) const
00437   {
00438     audit();
00439     o.audit();
00440 
00441     refine_using(o.ii_);
00442     o.refine_using(ii_);
00443 
00444     do {
00445       audit(); o.audit();
00446 
00447       CGAL::Comparison_result cmp;
00448       if (try_compare(o, cmp)) return cmp;
00449     
00450       refine();
00451       o.refine();
00452     } while (ii_.second-ii_.first  > NT(.0000001));
00453 
00454     //std::cout << "Using sturm to compare " << *this << " and " << o << std::endl;
00455 
00456     typename Traits::Compare_isolated_roots_in_interval pred=kernel_.compare_isolated_roots_in_interval_object(function_,o.function_);
00457     Comparison_result co= pred(ii_.first, ii_.second);
00458     //std::cout << "The result is " << co << std::endl;
00459     return co;
00460   }
00461 
00463   void audit() const
00464   {
00465     CGAL_Polynomial_assertion(!is_null());
00466 #ifndef NDEBUG
00467     bool problem=false;
00468     if (type_&INF) {
00469 
00470     } else if (ii_.first == ii_.second) {
00471       
00472     } else {
00473       if (is_up()) {
00474         problem = problem || (sign_at(ii_.first) != NEGATIVE);
00475         problem = problem || (sign_at(ii_.second) != POSITIVE);
00476       } else {
00477         problem = problem || (sign_at(ii_.first) != POSITIVE);
00478         problem = problem || (sign_at(ii_.second) != NEGATIVE);
00479       }
00480     }
00481     if (problem) {
00482       std::cerr << "Problem with interval.\n";
00483       std::cerr << "Type is " << type_ << std::endl;
00484       std::cerr << ii_.first << "..." << ii_.second << ", " << sign_at(ii_.first) 
00485                 << sign_at(ii_.second) << std::endl;
00486       CGAL_Polynomial_exactness_assertion(0);
00487     }
00488 #endif
00489   }
00490 
00491 
00492 
00493   CGAL::Sign sign_at(const NT &nt) const
00494   {
00495     return kernel_.sign_at_object()(function_, nt);
00496   }
00497 
00499   /*static This negative_infinity(){
00500     This ret(INF);
00501     //ret.set_type(INF);
00502     //ret.compute_approximation();
00503     return ret;
00504     }*/
00505 
00506   bool try_compare(const This &o, CGAL::Comparison_result &cmp) const {
00507     if (ii_.first == ii_.second){
00508       if (o.ii_.first == o.ii_.second) {
00509         cmp= CGAL::compare(ii_.first, o.ii_.second);
00510         return true;
00511       } else {
00512         if (o.ii_.first < ii_.first && o.ii_.second > ii_.first) {
00513           return false;
00514         } else {
00515           cmp= CGAL::compare(ii_.first, o.ii_.first);
00516           if (cmp == CGAL::EQUAL){
00517             cmp=  CGAL::compare(ii_.first, o.ii_.second);
00518           }
00519           //CGAL_assertion(CGAL::compare(ii_.second, o.ii_.second) == cmp);
00520           return true;
00521         }
00522       }
00523     } else if (o.ii_.first == o.ii_.second) {
00524       if (ii_.first < o.ii_.first && ii_.second > o.ii_.first) {
00525           return false;
00526         } else {
00527           cmp= CGAL::compare(ii_.first, o.ii_.first);
00528           if (cmp == CGAL::EQUAL) {
00529             cmp=  CGAL::compare(ii_.second, o.ii_.first);
00530           }
00531           //CGAL_assertion(CGAL::compare(ii_.second, o.ii_.second) == cmp);
00532           return true;
00533         }
00534     } else {
00535       if (ii_.first >= o.ii_.second) {
00536         cmp= CGAL::LARGER;
00537         return true;
00538       } else if (ii_.second <= o.ii_.first) {
00539         cmp= CGAL::SMALLER;
00540         return true;
00541       } else return false;
00542     }
00543   }
00544 
00545   bool is_up() const
00546   {
00547     return type_&UP;
00548   }
00549   bool is_down() const
00550   {
00551     return !(type_&UP);
00552   }
00553 
00554   static double double_inf_rep() {
00555     if (std::numeric_limits<double>::has_infinity) {
00556       return (std::numeric_limits<double>::infinity());
00557     } else return ((std::numeric_limits<double>::max)());
00558   }
00559 
00560   Sign lower_sign() const
00561   {
00562     CGAL_Polynomial_precondition(!is_infinite());
00563     if (is_up()) return NEGATIVE;
00564     else return POSITIVE;
00565   }
00566 
00568   void compute_approximation() {
00569 #ifndef NDEBUG
00570     approximation_=immutable_double_approximation(0.0001);
00571 #endif
00572   }
00573 
00574   double immutable_double_approximation(double accuracy=0.00001) const
00575   {
00576     CGAL_Polynomial_expensive_precondition(!is_null());
00577     This temp = *this;
00578     return temp.internal_compute_interval(accuracy).first;
00579   }
00580 
00582   bool is_null() const
00583   {
00584     return (type_&INVALID);
00585   }
00586 
00587   mutable std::pair<NT, NT> ii_;
00588   //Function f_;
00589   Type type_;
00590   Polynomial function_;
00591   Traits kernel_;
00592   mutable std::pair<double,double> interval_;
00593 #ifndef NDEBUG
00594   double approximation_;
00595 #endif
00596 };
00597 
00598 /*
00599   template <class F>
00600   double to_double(const Simple_interval_root<F> &f){
00601   return f.to_double();
00602   }
00603 
00604   template <class F>
00605   std::pair<double,double> to_interval(const Simple_interval_root<F> &f){
00606   return f.to_ii_;
00607   }*/
00608 
00609 template <class F>
00610 std::ostream &operator<<(std::ostream &out, const Simple_interval_root<F> &f)
00611 {
00612   f.write(out);
00613   return out;
00614 }
00615 
00616 /*
00617 template <class F>
00618 bool root_is_even_multiplicity(const Simple_interval_root<F> &f)
00619 {
00620   return f.is_even_multiplicity();
00621 }
00622 
00623 
00624 template <class F>
00625 typename F::NT to_rational(const Simple_interval_root<F> &f)
00626 {
00627   return f.to_rational();
00628 }
00629 
00630 
00631 template <class F>
00632 bool is_rational(const Simple_interval_root<F> &f)
00633 {
00634   return f.is_rational();
00635   }*/
00636 
00637 
00638 CGAL_POLYNOMIAL_END_INTERNAL_NAMESPACE
00639 
00640 CGAL_BEGIN_NAMESPACE
00641 
00642 
00643 template <class T>
00644 class Real_embeddable_traits< CGAL::POLYNOMIAL::internal::Simple_interval_root<T> > 
00645   : public INTERN_RET::Real_embeddable_traits_base< CGAL::POLYNOMIAL::internal::Simple_interval_root<T> , Tag_true > {
00646 public:
00647   typedef CGAL::POLYNOMIAL::internal::Simple_interval_root<T>  Type;
00648   class Abs 
00649     : public std::unary_function< Type, Type > {
00650   public:
00651     Type operator()( const Type& x ) const {
00652       if (x < Type(0)) return -x;
00653       else return x;
00654     }
00655   };
00656     
00657   class Sgn 
00658     : public std::unary_function< Type, ::CGAL::Sign > {
00659   public:
00660     ::CGAL::Sign operator()( const Type& x ) const {
00661       return static_cast<CGAL::Sign>(x.compare(0));
00662     }        
00663   };
00664     
00665   class Compare 
00666     : public std::binary_function< Type, Type,
00667                               Comparison_result > {
00668   public:
00669     Comparison_result operator()( const Type& x, 
00670                                   const Type& y ) const {
00671       return x.compare(y);
00672     }
00673         
00674     CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT( Type,
00675                                                          Comparison_result )
00676         
00677       };
00678     
00679   class To_double 
00680     : public std::unary_function< Type, double > {
00681   public:
00682     double operator()( const Type& x ) const {
00683       // this call is required to get reasonable values for the double
00684       // approximation
00685       return x.compute_double(.00000001);
00686     }
00687   };
00688     
00689   class To_interval 
00690     : public std::unary_function< Type, std::pair< double, double > > {
00691   public:
00692     std::pair<double, double> operator()( const Type& x ) const {
00693 
00694       return x.compute_interval(.00001);
00695     }          
00696   };
00697 };
00698 
00699 
00700 
00701 CGAL_END_NAMESPACE
00702 
00703 namespace std
00704 {
00705   template <class Tr>
00706   class numeric_limits<CGAL_POLYNOMIAL_NS::internal::Simple_interval_root<Tr> >
00707   {
00708   public:
00709     typedef CGAL_POLYNOMIAL_NS::internal::Simple_interval_root<Tr> T;
00710     static const bool is_specialized = true;
00711     static T min BOOST_PREVENT_MACRO_SUBSTITUTION () throw () {return -T::infinity();}
00712     static T max BOOST_PREVENT_MACRO_SUBSTITUTION () throw () {return T::infinity();}
00713     static const int digits =0;
00714     static const int digits10 =0;
00715     static const bool is_signed = true;
00716     static const bool is_integer = false;
00717     static const bool is_exact = true;
00718     static const int radix =0;
00719     static T epsilon() throw(){return T(0);}
00720     static T round_error() throw(){return T(0);}
00721     static const int min_exponent=0;
00722     static const int min_exponent10=0;
00723     static const int max_exponent=0;
00724     static const int max_exponent10=0;
00725     static const bool has_infinity=true;
00726     static const bool has_quiet_NaN = true;
00727     static const bool has_signaling_NaN= false;
00728     static const float_denorm_style has_denorm= denorm_absent;
00729     static const bool has_denorm_loss = false;
00730     static T infinity() throw() {return T::infinity();}
00731     static T quiet_NaN() throw(){return T();}
00732     static T denorm_min() throw() {return T(0);}
00733     static const bool is_iec559=false;
00734     static const bool is_bounded =false;
00735     static const bool is_modulo= false;
00736     static const bool traps = false;
00737     static const bool tinyness_before =false;
00738     static const float_round_style round_stype = round_toward_zero;
00739   };
00740 };
00741 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines