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 + -
显示快捷键?