CGAL 4.13 - Number Types
1 Introduction(介绍:略)
涉及到的数大致有3种:一是整数,二是有理数,三是浮点数。有理数可以用2个整数表示。精度上可分为任意精度和固定精度,固定精度可能会出现舍入。还有一种用于表示区间的数据,可用于求解多项式,要求其精度不断提高,从而找到解的位置。
2 Built-in Number Types(内置类型)
The built-in number types float
, double
and long double
have the required arithmetic and comparison operators. They lack some required routines though which are automatically included by CGAL. [1]
内置数据类型包括float,double和long double有所需的算术和比较运算符。
All built-in number types of C++ can represent a discrete (bounded) subset of the rational numbers only. We assume that the floating-point arithmetic of your machine follows Ieee floating-point standard. Since the floating-point culture has much more infrastructural support (hardware, language definition and compiler) than exact computation, it is very efficient. Like with all number types with finite precision representation which are used as approximations to the infinite ranges of integers or real numbers, the built-in number types are inherently potentially inexact. Be aware of this if you decide to use the efficient built-in number types: you have to cope with numerical problems. For example, you can compute the intersection point of two lines and then check whether this point lies on the two lines. With floating point arithmetic, roundoff errors may cause the answer of the check to be false
. With the built-in integer types overflow might occur.
假定内置数据类型符合IEEE浮点标准,它运行十分高效,但不精确。如在确定一个点是否在两条件线的交点上时,可能会算不准。
3 Number Types Provided by CGAL(CGAL提供的数据类型)
CGAL provides several number types that can be used for exact computation. These include the Quotient
class that can be used to create, for example, a number type that behaves like a rational number when parameterized with a number type which can represent integers.
The number type 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 Quotient
, one obtains rational numbers. Note that MP_Float
may not be as efficient as the integer types provided by Gmp or 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 Lazy_exact_nt<NT>
is able to represent any number that NT
is able to represent, but because it first tries to use an approximate value to perform computations it can be faster than NT
.
A number type for doing interval arithmetic, Interval_nt
, is provided. This number type helps in doing arithmetic filtering in many places such as Filtered_predicate
.
Sqrt_extension
is a number type that allows to represent algebraic numbers of degree 2 as well as nested forms. A generic function make_root_of_2()
allows to build this type generically.
A debugging helper Number_type_checker<NT1,NT2,Comparator>
is also provided which allows to compare the behavior of operations over two number types.
CGAL提供了几种数据类型用于精确计算。包括Quotient类,它可用于创建一种行为类似有理数的类型。
(1)MP_Float类型能够表示多精度浮点数值,一种整数的泛化,由平方(可能是负2)来缩放。它可用于处理与所需有理数进行的浮点数环运算。将它插入Quotient类中,我们得到有理数。MP_Float可能不如GMP或LEDA提供的整数高效,但它可以摆脱外部库的依赖。
(2)Lazy_exact_nt<NT>是带模板的类型,能表示NT表示的任何数,但它使用一种近似值来进行运算,所以可比NT运算更加快。
(3)Interval_nt用于进行区间运算,可在如Filtered_predicate等断言中用于算术过滤
(4)Sqrt_extension类型可用于表示二次(degree 2)代数数集或内嵌形式(nested forms),通用函数make_root_2()一般用于创建这种类型。(这里不懂)
(5)Number_type_checker<NT1,NT2,Comparator>用于调试,它允许比较两种数据类型的运算行为。
4 Number Types Provided by GMP(GMP提供的数据类型)
CGAL provides wrapper classes for number types defined in the Gnu Multiple Precision arithmetic library [2]. The file CGAL/Gmpz.h
provides the class Gmpz
, a wrapper class for the arbitrary-precision integer type mpz_t
, which is compliant with the CGAL number type requirements. The file CGAL/Gmpq.h
provides the class Gmpq
, a wrapper class for the arbitrary-precision rational type mpq_t
, which is compliant with the CGAL number type requirements.
The file CGAL/Gmpzf.h
provides the class Gmpzf
, an exact arbitrary-precision floating-point type. Hence, It does not support operators like /
to guarantee exactness of the operations. The arithmetic operations on this type are restricted to +
, -
, *
and integral_division()
. On some platforms, the file CGAL/Mpzf.h
provides the class Mpzf
, a faster alternative to Gmpzf
that doesn't support integral_division()
.
The file CGAL/Gmpfr.h
provides the class Gmpfr
, a fixed-precision floating-point number type. Since the precision (number of bits used to represent the mantissa of the number) is fixed for each object, the result of each operation is rounded when necessary. Though not necessary at first, the user will take full advantage of this number type by understanding the ideas behind floating-point arithmetic, such as precision and rounding, and understanding the flags set by this library after each operation. For more details, the reader should refer to [5] and the Gmpfr
reference manual.
In addition, it is possible to directly use the C++ number types provided by Gmp : mpz_class
, mpq_class
(note that support for mpf_class
is incomplete). The file CGAL/gmpxx.h
provides the necessary functions to make these classes compliant to the CGAL number type requirements.
CGAL提供了GMP类型的封装类。CGAL/Gmpz.h提供了绝对(任意)精度整数类型mpz_t的封装类Gmpz。CGAL/Gmpq.h提供了绝对精度有理数类型mpq_t的封装类Gmpq。
CGAL/Gmpzf.h提供了精确的任意精度的浮点数类型 Gmpzf
,所以它不支持如/(除法)等运算来保证精确性。其算术运算限于+,-,*和integral_division()。在一些平台上文件CGAL/Mpzf.h提供了Mpzf类,它可替代Gmpzf类,运行较快,不支持integral_division()。
CGAL/Gmpfr.h提供了一个固定精确度的浮点类型Gmpfr。因为精度是固定的,所以在运算中可能会出现舍入。
另外,CGAL可以直接使用GMP提供的C++数据类型 mpz_class和 mpq_class(这里注意,CGAL对mpf_class的支持是不完整的)。CGAL/gmpxx.h提供了所需的函数使这些类适用于CGAL数据类型的要求。
5 Number Types Provided by LEDA(LEDA提供的数据类型)
LEDA provides number types that can be used for exact computation with both Cartesian and homogeneous representations. If you are using homogeneous representation with the built-in integer types short
, int
, and long
as ring type, exactness of computations can be guaranteed only if your input data come from a sufficiently small integral range and the depth of the computations is sufficiently small. LEDA provides the number type leda_integer
for integers of arbitrary length. (Of course the length is somehow bounded by the resources of your computer.) It can be used as ring type in homogeneous kernels and leads to exact computation as long as all intermediate results are rational. For the same kind of problems, Cartesian representation with number type leda_rational
leads to exact computation as well. The number type leda_bigfloat
in LEDA is a variable precision floating-point type. Rounding mode and precision (i.e. mantissa length) of leda_bigfloat
can be set.
The most sophisticated number type in LEDA is the number type called leda_real
. Like in Pascal, where the name real
is used for floating-point numbers, the name leda_real
does not describe the number type precisely, but intentionally. leda_real
is a subset of real algebraic numbers. Any integer is leda_real
and leda_real
is closed under the operations +,−,∗,/and k-th root computation. For LEDA version 5.0 and or later leda_real
is also able to represent real roots of polynomials. leda_real
s guarantee that all comparisons between expressions involving leda_real
produce the exact result.
The files CGAL/leda_integer.h
, CGAL/leda_rational.h
, CGAL/leda_bigfloat.h
and CGAL/leda_real.h
provide the necessary functions to make these classes compliant to the CGAL number type requirements.
LEDA提供了能用于笛卡尔或齐次表达中精确计算的数据类型。C++或C内置的数据类型,如short、int、long作为环类型,只能在较小范围内保证(输入的范围和运算的深度)精度。LEDA提供leda_integer表示任意长整数。它可在齐次内核中作为环类型,只要所有的中间结果是有理的,它就可进行精确计算。同样类型的问题LEDA提供了leda_rational类型在笛卡尔表达中同样可进行精确计算。Leda_bigfloat是一种可变精度的浮点类型,舍入模式和有效位可以进行设置。
Leda_real 类型的名称并不精确表述了该类型内涵。它是实数代数数集的一个子集,任意整数是一个leda_real。Leda_real对于+、-、*、/和K阶根运算封闭。5.0版之后leda_real也可表示多项式的实根。Leda_real确保涉及到它的所有比较能够产生精确结果。
这些类型分别在CGAL/leda_integer.h, CGAL/leda_rational.h, CGAL/leda_bigfloat.h and CGAL/leda_real.h文件中,并通过函数使之符合CGAL要求。
6 Number Types Provided by CORE(由内核提供的数据类型)
In principle Core [3] provides the same set of number types as LEDA. The type CORE::BigInt
represent integers and CORE::BigRat
represent rationals of arbitrary length. The number type CORE::BigFloat
is a variable precision floating-point type. It is also possible to interpret it as an interval type, since it also carries the error of a computed value. As for LEDA, the most sophisticated number type in Core is CORE::Expr
, which is in its functionality equivalent to leda_real
.
在基本Core中,提供了与LEDA相同的类型集。CORE::BigInt表示整数,CORE::BigRat表示任意长度的有理数。CORE::BigFloat类型是一个可变精度的浮点类型,也可将其作为区间类型,因为它也带有运算值的误差。CORE::Expr类型与LEDA中的leda_real类型在功能上相同。
7 Interval Arithmetic(区间算术)
Interval arithmetic is very important for geometric programming. It is a fundamental tool for filtering predicates. For many problems, intervals of machine double-precision numbers are sufficient, but it is not always enough. For example, one approach for determining the sign of an expression is to evaluate its sign using interval arithmetic and to repeatedly increase the precision of the bounds of the intervals until either the interval does not contain zero or its width is less than the separation bound of the polynomial.
区间运算十分重要。有时机内的双精度数不能满足要求,如确定一个多项式的符号时,要不断提高精度,直到区间中不包含0或精度超过了多项式的值域。
For intervals of machine double-precision numbers, CGAL provides the class Interval_nt
. For intervals of floating-point arbitrary-precision numbers, CGAL provides the class Gmpfi
.
CGAL提供了Interval_nt来进行双精度区间运算,提供了Gmpfi来表示任意精度的浮点数。
Endpoints of Gmpfi
intervals are represented as Gmpfr
numbers. Each interval has an associated precision, which is the maximum precision (number of bits used to represent the mantissa) of its endpoints. The result of the operations is guaranteed to be always contained in the returned interval. Since the interval arithmetic is implemented on top of Gmpfr
, the global flags are inherited from the Gmpfr
interface. See [4] and the Gmpfi
reference manual for details.
Gmpfi区间的端点用于Gmpfr类型数据来表示。每个区间有一个精确度,表示数的有效尾数。
To use the Gmpfi
class, Mpfi must be installed.
为了使用Gmpfi,MPFI必须安装
8 User-supplied Number Types(用户提供的数据类型)
In order to use your own number type it must be a model of the according algebraic structure concept, in particular you must provide a specialization of Algebraic_structure_traits
and also of Real_embeddable_traits
in case it is a sub ring of the real numbers. If you even want to provide a related ensemble of number types you should also provide specializations for Coercion_traits
in order to reflect their interoperability.
为了使用用户自定类型,必须提供一个Algebraic_structure_traits的特化(specialization)类型,如果数是实数的一个子环时也需要提供Real_embeddable_traits的特化类型。如果你要提供一个相关的数据类型集,你需要提供Coercion_traits的特化,用于表示它们之间的交互。
9 Design and Implementation History
This package was naturally one of the first packages implemented in CGAL. It initially contained the Quotient
, Gmpz
and Gmpq
classes, together with the interfaces to the number types provided by LEDA, which were implemented by Stefan Schirra and Andreas Fabri.
Later, around 1998-2002, Sylvain Pion implemented Interval_nt
, MP_Float
and Lazy_exact_nt
, together with the interfaces to the mpz_class
and mpq_class
types from Gmp.
Number type concepts were then refined, notably by Lutz Kettner and Susan Hert, who also contributed utility algorithms.
The work on concepts was further extended within the Exacus project, and was finally contributed to CGAL by Michael Hemmer in 2006, as what is now the separate package Algebraic Foundations, together with a rewritten interface to operations on number types.
The class Sqrt_extension
was contributed by Michael Hemmer and Ron Wein around 2006. In 2010 it went through a considerable reinvestigation by Sébastien Loriot, Michael Hemmer, and Monique Teillaud. As a result it got further improved and now replaces several similar types such as Root_of_2
, which had been contributed by Pedro M. M. de Castro, Sylvain Pion and Monique Teillaud, and is deprecated since CGAL-3.8.