Add and document functions that make MP_Float a EuclideanRingNumberType.

This commit is contained in:
Sylvain Pion 2006-08-24 09:31:53 +00:00
parent 230e6f63e0
commit 67097a3ff3
5 changed files with 78 additions and 24 deletions

View File

@ -102,17 +102,24 @@ With the built-in integer types overflow might occur.
\cgal\ provides several number types that are that can be used for \cgal\ provides several number types that are that can be used for
exact computation. These include the \ccc{Quotient} class that can exact computation. These include the \ccc{Quotient} class that can
be used to create, for example, a number type that behaves like a rational be used to create, for example, a number type that behaves like a rational
number. When used in conjunction with the number type \ccc{MP_Float} that number when parameterized with a number type which can represent integers.
is able to represent multi-precision floating point values, you achieve
an exact rational number representation. The number type \ccc{MP_Float} is able to represent multi-precision floating
point values, a generalization of integers scaled by a (potentially negative)
power of 2. It allows to deal with ring operations over floating-point values
with requiring rational numbers. By plugging it in \ccc{Quotient}, one obtains
rational numbers. Note that \ccc{MP_Float} may not be as efficient as the
integer types provided by \ccc{GMP} or \ccc{LEDA}, but it has the advantage
to make more parts of \cgal\ independent on these external libraries for
handling robustness issues.
The templated number type \ccc{Lazy_exact_nt<NT>} is able to represent any The templated number type \ccc{Lazy_exact_nt<NT>} is able to represent any
number that \ccc{NT} is able to represent, but because it first tries to use an number that \ccc{NT} is able to represent, but because it first tries to use an
approximate value to perform computations it can be faster than the provided approximate value to perform computations it can be faster than \ccc{NT}.
number type \ccc{NT}. \cgal\ also provides a fixed-precision number type,
A number type for doing interval arithmetic, \ccc{Interval_nt}, is provided. A number type for doing interval arithmetic, \ccc{Interval_nt}, is provided.
This number type helps in doing filtering of predicates. This number type helps in doing arithmetic filtering in many places such
as \ccc{Filtered_predicate}.
\ccc{CGAL::Root_of_2} is a number type that allows to represent algebraic \ccc{CGAL::Root_of_2} is a number type that allows to represent algebraic
numbers of degree up to~2 over a \ccc{RingNumberType}. A generic function numbers of degree up to~2 over a \ccc{RingNumberType}. A generic function

View File

@ -39,6 +39,7 @@ RingNumberType
\ccc{int} \\ \ccc{int} \\
\ccc{long} \\ \ccc{long} \\
\ccc{long long} \\ \ccc{long long} \\
\ccc{CGAL::MP_Float} \\
\ccc{CGAL::Gmpz} \\ \ccc{CGAL::Gmpz} \\
\ccc{leda_integer} \ccc{leda_integer}

View File

@ -33,7 +33,6 @@ RingNumberType
\ccc{CGAL::Interval_nt} \\ \ccc{CGAL::Interval_nt} \\
\ccc{CGAL::Interval_nt_advanced} \\ \ccc{CGAL::Interval_nt_advanced} \\
\ccc{CGAL::Lazy_exact_nt<FieldNumberType>} \\ \ccc{CGAL::Lazy_exact_nt<FieldNumberType>} \\
\ccc{CGAL::MP_Float} \\
\ccc{CGAL::Quotient<RingNumberType>} \\ \ccc{CGAL::Quotient<RingNumberType>} \\
\ccc{leda_rational} \\ \ccc{leda_rational} \\
\ccc{leda_bigfloat} \\ \ccc{leda_bigfloat} \\

View File

@ -8,18 +8,17 @@
\ccDefinition \ccDefinition
An object of the class \ccc{MP_Float} is able to represent a floating point An object of the class \ccc{MP_Float} is able to represent a floating point
value with arbitrary precision. This number type has the property that value with arbitrary precision, that is numbers of the form $m2^e$ where
$m$ and $e$ are integers. This number type has the property that
additions, subtractions and multiplications are computed exactly, as well as additions, subtractions and multiplications are computed exactly, as well as
the construction from \ccc{float}, \ccc{double} and \ccc{long double}. the construction from \ccc{float}, \ccc{double} and \ccc{long double}.
It also provides integral divisions related operations.
Division and square root are not enabled by default since \cgal\ release 3.2, Square root and (field) division are not enabled by default since
since they are computed approximately. We suggest that you use \cgal\ release 3.2, since they are computed approximately. We suggest that you
rationals like \ccc{Quotient<MP_Float>} when you need exact (rational) use rationals like \ccc{Quotient<MP_Float>} when you need exact (rational)
divisions. divisions. To enable division and square root, you have to define the
To enable division and square root, you have to define the preprocessor preprocessor macro \ccc{CGAL_MP_FLOAT_ALLOW_INEXACT}.
macro \ccc{CGAL_MP_FLOAT_ALLOW_INEXACT}.
An exact (integral) division is also provided.
Note on the implementation : although the mantissa length is basically only Note on the implementation : although the mantissa length is basically only
limited by the available memory, the exponent is currently represented by a limited by the available memory, the exponent is currently represented by a
@ -29,8 +28,7 @@ plan to also have a multiprecision exponent to fix this issue.
\ccInclude{CGAL/MP_Float.h} \ccInclude{CGAL/MP_Float.h}
\ccIsModel \ccIsModel
\ccc{RingNumberType} \ccc{EuclideanRingNumberType}
or \ccc{SqrtFieldNumberType} if \ccc{CGAL_MP_FLOAT_ALLOW_INEXACT} is set.
\ccCreation \ccCreation
\ccCreationVariable{m} \ccCreationVariable{m}
@ -62,16 +60,33 @@ or \ccc{SqrtFieldNumberType} if \ccc{CGAL_MP_FLOAT_ALLOW_INEXACT} is set.
{reads a \ccc{double} from \ccc{in}, then converts it to an \ccc{MP_Float}.} {reads a \ccc{double} from \ccc{in}, then converts it to an \ccc{MP_Float}.}
\ccFunction{bool divides(const MP_Float &a, const MP_Float &b);} \ccFunction{bool divides(const MP_Float &a, const MP_Float &b);}
{returns true iff \ccc{b} divides \ccc{b}.} {returns true iff \ccc{b} divides \ccc{a}.}
\ccFunction{MP_Float exact_division(const MP_Float &a, const MP_Float &b);} \ccFunction{MP_Float exact_division(const MP_Float &a, const MP_Float &b);}
{computes the result of the division of \ccc{a} by \ccc{b}. {computes the result of the division of \ccc{a} by \ccc{b}.
\ccPrecond{divides(a, b)}.} \ccPrecond{divides(a, b)}.}
\ccFunction{MP_Float div(const MP_Float &a, const MP_Float &b);}
{returns the result of the integral division of \ccc{a} by \ccc{b}.
For \ccc{MP_Float}, this is not uniquely defined, but this function
guarantees that the remainder has a smaller bitlength than \ccc{b}
(considering the bitlength of the odd mantissa).}
\ccFunction{MP_Float operator%(const MP_Float &a, const MP_Float &b);}
{returns the remainder of the integral division of \ccc{a} by \ccc{b}.
For \ccc{MP_Float}, this is not uniquely defined, but this function
guarantees that the remainder has a smaller bitlength than \ccc{b}
(considering the bitlength of the odd mantissa).}
\ccFunction{MP_Float gcd(const MP_Float &a, const MP_Float &b);}
{returns the greatest common divisor of \ccc{a} and \ccc{b}.
For \ccc{MP_Float}, this is defined up to a power of 2.}
\ccPrecond{\ccc{a} and \ccc{b} are non zero.}}
\ccFunction{MP_Float approximate_division(const MP_Float &a, const MP_Float &b);} \ccFunction{MP_Float approximate_division(const MP_Float &a, const MP_Float &b);}
{computes an approximation of the division by converting the operands to {computes an approximation of the (field) division by converting the operands
\ccc{double}, performing the division on \ccc{double}, and converting back to to \ccc{double}, performing the division on \ccc{double}, and converting back
\ccc{MP_Float}.} to \ccc{MP_Float}.}
\ccFunction{MP_Float approximate_sqrt(const MP_Float &a);} \ccFunction{MP_Float approximate_sqrt(const MP_Float &a);}
{computes an approximation of the square root by converting the operand to {computes an approximation of the square root by converting the operand to

View File

@ -37,6 +37,7 @@
// The main algorithms are : // The main algorithms are :
// - Addition/Subtraction // - Addition/Subtraction
// - Multiplication // - Multiplication
// - Integral division div(), exact_division(), gcd(), operator%().
// - Comparison // - Comparison
// - to_double() / to_interval() // - to_double() / to_interval()
// - Construction from a double. // - Construction from a double.
@ -49,8 +50,6 @@
// - Division, sqrt... : different options : // - Division, sqrt... : different options :
// - nothing // - nothing
// - convert to double, take approximation, compute over double, reconstruct // - convert to double, take approximation, compute over double, reconstruct
// - exact division as separate function (for Bareiss...)
// - returns the quotient of the division, forgetting the rest.
CGAL_BEGIN_NAMESPACE CGAL_BEGIN_NAMESPACE
@ -62,6 +61,7 @@ MP_Float operator*(const MP_Float &a, const MP_Float &b);
#ifdef CGAL_MP_FLOAT_ALLOW_INEXACT #ifdef CGAL_MP_FLOAT_ALLOW_INEXACT
MP_Float operator/(const MP_Float &a, const MP_Float &b); MP_Float operator/(const MP_Float &a, const MP_Float &b);
#endif #endif
MP_Float operator%(const MP_Float &a, const MP_Float &b);
Comparison_result Comparison_result
compare (const MP_Float & a, const MP_Float & b); compare (const MP_Float & a, const MP_Float & b);
@ -191,6 +191,7 @@ public:
#ifdef CGAL_MP_FLOAT_ALLOW_INEXACT #ifdef CGAL_MP_FLOAT_ALLOW_INEXACT
MP_Float& operator/=(const MP_Float &a) { return *this = *this / a; } MP_Float& operator/=(const MP_Float &a) { return *this = *this / a; }
#endif #endif
MP_Float& operator%=(const MP_Float &a) { return *this = *this % a; }
exponent_type max_exp() const exponent_type max_exp() const
{ {
@ -597,6 +598,37 @@ divides(const MP_Float & n, const MP_Float & d)
return CGALi::division(n, d).second == 0; return CGALi::division(n, d).second == 0;
} }
inline
MP_Float
operator%(const MP_Float& n1, const MP_Float& n2)
{
return CGALi::division(n1, n2).second;
}
inline
MP_Float
div(const MP_Float& n1, const MP_Float& n2)
{
return CGALi::division(n1, n2).first;
}
inline
MP_Float
gcd( const MP_Float& a, const MP_Float& b)
{
CGAL_precondition( a != 0 );
CGAL_precondition( b != 0 );
MP_Float x = a, y = b;
while (true) {
x = x % y;
if (x == 0) {
CGAL_postcondition(divides(a, y) && divides(b, y));
return y;
}
swap(x, y);
}
}
CGAL_END_NAMESPACE CGAL_END_NAMESPACE
#endif // CGAL_MP_FLOAT_H #endif // CGAL_MP_FLOAT_H