gmp_double.h
来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 520 行
H
520 行
// Copyright (c) 1999,2003,2004 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.//// $Source: /CVSROOT/CGAL/Packages/_QP_solver/include/CGAL/_QP_solver/gmp_double.h,v $// $Revision: 1.8 $ $Date: 2004/09/21 06:48:05 $// $Name: $//// Author(s) : Sven Schoenherr <sven@inf.ethz.ch>#ifndef GMP_DOUBLE_H#define GMP_DOUBLE_H// includes#include <CGAL/_QP_solver/gmp_integer.h>#include <iostream>#include <cmath>namespace GMP {// Class declaration// =================class Double;// Function declaration// ====================inline std::ostream& operator << ( std::ostream&, const Double&);// Class interface// ===============class Double { public: // types typedef GMP::Integer Mantissa; typedef long Exponent; // construction Double( ); Double( const Double&); Double( int); Double( double); Double( const Mantissa&, const Exponent&); // comparisons bool operator == ( const Double&) const; bool operator != ( const Double&) const; bool operator < ( const Double&) const; bool operator > ( const Double&) const; bool operator <= ( const Double&) const; bool operator >= ( const Double&) const; // arithmetic operations Double operator - ( ) const; Double operator + ( const Double&) const; Double operator - ( const Double&) const; Double operator * ( const Double&) const; Double operator / ( const Double&) const; // arithmetic assignment operations Double& operator += ( const Double&); Double& operator -= ( const Double&); Double& operator *= ( const Double&); Double& operator /= ( const Double&); // shift operations Double operator << ( unsigned long) const; Double operator >> ( unsigned long) const; // shift assignment operations Double& operator <<= ( unsigned long); Double& operator >>= ( unsigned long); // sign function int sign( ) const; // conversion function double to_double( ) const; // access functions to the internal representation const Mantissa& mantissa( ) const; const Exponent& exponent( ) const; // normalization bool is_normal( ) const; void normalize( ); private: // data members Mantissa m; Exponent e;};// ============================================================================// Class implementation// ====================// normalization// -------------// is normalized?inlineboolDouble::is_normal( ) const{ return ( m.zeros() == 0);}// normalizeinlinevoidDouble::normalize( ){ if ( m == 0) e = 0; else { int zeros = m.zeros(); m >>= zeros; e += zeros; }}// construction// ------------// default constructorinlineDouble::Double( ) : e( 0){ }// copy constructorinlineDouble::Double( const Double& d) : m( d.m), e( d.e){ }// constructor (int)inlineDouble::Double( int i) : m( i), e( 0){ }// constructor (double)inlineDouble::Double( double d){ if ( d == 0.0) e = 0; else { int exp; double x = frexp( d, &exp); m = Mantissa( ldexp( x, 53)); e = exp-53; normalize(); }}// constructor (mantissa, exponent)inlineDouble::Double( const Mantissa& mantissa, const Exponent& exponent) : m( mantissa), e( exponent){ normalize();}// comparisons// -----------// equalinlineboolDouble::operator == ( const Double& d) const{ if ( e < d.e) return ( m == ( d.m << ( d.e - e))); if ( e > d.e) return ( ( m << ( e - d.e)) == d.m ); return ( m == d.m);}// not equalinlineboolDouble::operator != ( const Double& d) const{ return !( *this == d);}// lessinlineboolDouble::operator < ( const Double& d) const{ if ( e < d.e) return ( m < ( d.m << ( d.e - e))); if ( e > d.e) return ( ( m << ( e - d.e)) < d.m ); return ( m < d.m);}inline booloperator < (int i, const Double& d){ Double ld(i); return ld < d;}inline booloperator < (const Double& d, int i){ Double rd(i); return d < rd;}// greaterinlineboolDouble::operator > ( const Double& d) const{ return ( d < *this);}inline booloperator > (int i, const Double& d){ Double ld(i); return ld > d;}inline booloperator > (const Double& d, int i){ Double rd(i); return d > rd;}// less equalinlineboolDouble::operator <= ( const Double& d) const{ return !( d < *this);}// greater equalinlineboolDouble::operator >= ( const Double& d) const{ return !( *this < d);}// arithmetic operations// ---------------------// unary minusinlineDoubleDouble::operator - ( ) const{ return Double( -m, e);}// additioninlineDoubleDouble::operator + ( const Double& d) const{ if ( e < d.e) return Double( m + ( d.m << ( d.e - e)), e); if ( e > d.e) return Double( ( m << ( e - d.e)) + d.m, d.e); return Double( m + d.m, e);}// subtractioninlineDoubleDouble::operator - ( const Double& d) const{ if ( e < d.e) return Double( m - ( d.m << ( d.e - e)), e); if ( e > d.e) return Double( ( m << ( e - d.e)) - d.m, d.e); return Double( m - d.m, e);}// multiplicationinlineDoubleDouble::operator * ( const Double& d) const{ return Double( m * d.m, e + d.e);}// division (without remainder)inlineDoubleDouble::operator / ( const Double& d) const{ // only correct if division result is representable // as a Double and both operands are normalized if ( ! d.is_normal()) const_cast<Double&>( d).normalize(); if ( ! is_normal()) const_cast<Double*>( this)->normalize(); return Double( m / d.m, e - d.e);}// arithmetic assignment operations// --------------------------------// addition assignmentinlineDouble&Double::operator += ( const Double& d){ if ( e < d.e) { m += ( d.m << ( d.e - e)); return *this; } if ( e > d.e) { m = ( m << ( e - d.e)) + d.m; e = d.e; return *this; } // e == d.e m += d.m; return *this;}// subtraction assignmentinlineDouble&Double::operator -= ( const Double& d){ if ( e < d.e) { m -= ( d.m << ( d.e - e)); return *this; } if ( e > d.e) { m = ( m << ( e - d.e)) - d.m; e = d.e; return *this; } // e == d.e m -= d.m; return *this;}// multiplication assignmentinlineDouble&Double::operator *= ( const Double& d){ m *= d.m; e += d.e; return *this;}// division assignmentinlineDouble&Double::operator /= ( const Double& d){ // only correct if division result is representable // as a Double and both operands are normalized if ( ! d.is_normal()) const_cast<Double&>( d).normalize(); if ( ! is_normal()) normalize(); m /= d.m; e -= d.e; return *this;}// shift operations// ----------------// left shiftinlineDoubleDouble::operator << ( unsigned long i) const{ return Double( m, e+i);}// right shiftinlineDoubleDouble::operator >> ( unsigned long i) const{ return Double( m, e-i);} // shift assignment operations// ---------------------------// left shift assignmentinlineDouble&Double::operator <<= ( unsigned long i){ e += i; return *this;}// right shift assignmentinlineDouble&Double::operator >>= ( unsigned long i){ e -= i; return *this;}// sign function// -------------inlineintDouble::sign( ) const{ return m.sign();}// conversion functions// --------------------// conversion to doubleinlinedoubleDouble::to_double( ) const{ return ldexp( m.to_double(), e);}// Also add global function in this namespace for Koenig lookup.inlinedoubleto_double(const Double &d){ return d.to_double();}// access functions to the internal representation// -----------------------------------------------// mantissainlineconst Double::Mantissa&Double::mantissa( ) const{ return m;}// exponentinlineconst Double::Exponent&Double::exponent( ) const{ return e;}// I/O// ---// output operatorinlinestd::ostream&operator << ( std::ostream& out, const Double& d){ out << "( " << d.mantissa() << ", " << d.exponent() << ')'; return out;}} // namespace GMP#endif // GMP_DOUBLE_H// ===== EOF ==================================================================
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?