You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
401 lines
13 KiB
401 lines
13 KiB
<HTML>
|
|
<HEAD>
|
|
<!-- Created by texi2html 1.56k from cln.texi on 19 May 2000 -->
|
|
|
|
<TITLE>CLN, a Class Library for Numbers - 3. Ordinary number types</TITLE>
|
|
</HEAD>
|
|
<BODY>
|
|
Go to the <A HREF="cln_1.html">first</A>, <A HREF="cln_2.html">previous</A>, <A HREF="cln_4.html">next</A>, <A HREF="cln_13.html">last</A> section, <A HREF="cln_toc.html">table of contents</A>.
|
|
<P><HR><P>
|
|
|
|
|
|
<H1><A NAME="SEC11" HREF="cln_toc.html#TOC11">3. Ordinary number types</A></H1>
|
|
|
|
<P>
|
|
CLN implements the following class hierarchy:
|
|
|
|
|
|
|
|
<PRE>
|
|
Number
|
|
cl_number
|
|
<cl_number.h>
|
|
|
|
|
|
|
|
Real or complex number
|
|
cl_N
|
|
<cl_complex.h>
|
|
|
|
|
|
|
|
Real number
|
|
cl_R
|
|
<cl_real.h>
|
|
|
|
|
+-------------------+-------------------+
|
|
| |
|
|
Rational number Floating-point number
|
|
cl_RA cl_F
|
|
<cl_rational.h> <cl_float.h>
|
|
| |
|
|
| +-------------+-------------+-------------+
|
|
Integer | | | |
|
|
cl_I Short-Float Single-Float Double-Float Long-Float
|
|
<cl_integer.h> cl_SF cl_FF cl_DF cl_LF
|
|
<cl_sfloat.h> <cl_ffloat.h> <cl_dfloat.h> <cl_lfloat.h>
|
|
</PRE>
|
|
|
|
<P>
|
|
<A NAME="IDX7"></A>
|
|
<A NAME="IDX8"></A>
|
|
The base class <CODE>cl_number</CODE> is an abstract base class.
|
|
It is not useful to declare a variable of this type except if you want
|
|
to completely disable compile-time type checking and use run-time type
|
|
checking instead.
|
|
|
|
|
|
<P>
|
|
<A NAME="IDX9"></A>
|
|
<A NAME="IDX10"></A>
|
|
<A NAME="IDX11"></A>
|
|
The class <CODE>cl_N</CODE> comprises real and complex numbers. There is
|
|
no special class for complex numbers since complex numbers with imaginary
|
|
part <CODE>0</CODE> are automatically converted to real numbers.
|
|
|
|
|
|
<P>
|
|
<A NAME="IDX12"></A>
|
|
The class <CODE>cl_R</CODE> comprises real numbers of different kinds. It is an
|
|
abstract class.
|
|
|
|
|
|
<P>
|
|
<A NAME="IDX13"></A>
|
|
<A NAME="IDX14"></A>
|
|
<A NAME="IDX15"></A>
|
|
The class <CODE>cl_RA</CODE> comprises exact real numbers: rational numbers, including
|
|
integers. There is no special class for non-integral rational numbers
|
|
since rational numbers with denominator <CODE>1</CODE> are automatically converted
|
|
to integers.
|
|
|
|
|
|
<P>
|
|
<A NAME="IDX16"></A>
|
|
The class <CODE>cl_F</CODE> implements floating-point approximations to real numbers.
|
|
It is an abstract class.
|
|
|
|
|
|
|
|
|
|
<H2><A NAME="SEC12" HREF="cln_toc.html#TOC12">3.1 Exact numbers</A></H2>
|
|
<P>
|
|
<A NAME="IDX17"></A>
|
|
|
|
|
|
<P>
|
|
Some numbers are represented as exact numbers: there is no loss of information
|
|
when such a number is converted from its mathematical value to its internal
|
|
representation. On exact numbers, the elementary operations (<CODE>+</CODE>,
|
|
<CODE>-</CODE>, <CODE>*</CODE>, <CODE>/</CODE>, comparisons, ...) compute the completely
|
|
correct result.
|
|
|
|
|
|
<P>
|
|
In CLN, the exact numbers are:
|
|
|
|
|
|
|
|
<UL>
|
|
<LI>
|
|
|
|
rational numbers (including integers),
|
|
<LI>
|
|
|
|
complex numbers whose real and imaginary parts are both rational numbers.
|
|
</UL>
|
|
|
|
<P>
|
|
Rational numbers are always normalized to the form
|
|
<CODE><VAR>numerator</VAR>/<VAR>denominator</VAR></CODE> where the numerator and denominator
|
|
are coprime integers and the denominator is positive. If the resulting
|
|
denominator is <CODE>1</CODE>, the rational number is converted to an integer.
|
|
|
|
|
|
<P>
|
|
Small integers (typically in the range <CODE>-2^30</CODE>...<CODE>2^30-1</CODE>,
|
|
for 32-bit machines) are especially efficient, because they consume no heap
|
|
allocation. Otherwise the distinction between these immediate integers
|
|
(called "fixnums") and heap allocated integers (called "bignums")
|
|
is completely transparent.
|
|
|
|
|
|
|
|
|
|
<H2><A NAME="SEC13" HREF="cln_toc.html#TOC13">3.2 Floating-point numbers</A></H2>
|
|
<P>
|
|
<A NAME="IDX18"></A>
|
|
|
|
|
|
<P>
|
|
Not all real numbers can be represented exactly. (There is an easy mathematical
|
|
proof for this: Only a countable set of numbers can be stored exactly in
|
|
a computer, even if one assumes that it has unlimited storage. But there
|
|
are uncountably many real numbers.) So some approximation is needed.
|
|
CLN implements ordinary floating-point numbers, with mantissa and exponent.
|
|
|
|
|
|
<P>
|
|
<A NAME="IDX19"></A>
|
|
The elementary operations (<CODE>+</CODE>, <CODE>-</CODE>, <CODE>*</CODE>, <CODE>/</CODE>, ...)
|
|
only return approximate results. For example, the value of the expression
|
|
<CODE>(cl_F) 0.3 + (cl_F) 0.4</CODE> prints as <SAMP>`0.70000005'</SAMP>, not as
|
|
<SAMP>`0.7'</SAMP>. Rounding errors like this one are inevitable when computing
|
|
with floating-point numbers.
|
|
|
|
|
|
<P>
|
|
Nevertheless, CLN rounds the floating-point results of the operations <CODE>+</CODE>,
|
|
<CODE>-</CODE>, <CODE>*</CODE>, <CODE>/</CODE>, <CODE>sqrt</CODE> according to the "round-to-even"
|
|
rule: It first computes the exact mathematical result and then returns the
|
|
floating-point number which is nearest to this. If two floating-point numbers
|
|
are equally distant from the ideal result, the one with a <CODE>0</CODE> in its least
|
|
significant mantissa bit is chosen.
|
|
|
|
|
|
<P>
|
|
Similarly, testing floating point numbers for equality <SAMP>`x == y'</SAMP>
|
|
is gambling with random errors. Better check for <SAMP>`abs(x - y) < epsilon'</SAMP>
|
|
for some well-chosen <CODE>epsilon</CODE>.
|
|
|
|
|
|
<P>
|
|
Floating point numbers come in four flavors:
|
|
|
|
|
|
|
|
<UL>
|
|
<LI>
|
|
|
|
<A NAME="IDX20"></A>
|
|
Short floats, type <CODE>cl_SF</CODE>.
|
|
They have 1 sign bit, 8 exponent bits (including the exponent's sign),
|
|
and 17 mantissa bits (including the "hidden" bit).
|
|
They don't consume heap allocation.
|
|
|
|
<LI>
|
|
|
|
<A NAME="IDX21"></A>
|
|
Single floats, type <CODE>cl_FF</CODE>.
|
|
They have 1 sign bit, 8 exponent bits (including the exponent's sign),
|
|
and 24 mantissa bits (including the "hidden" bit).
|
|
In CLN, they are represented as IEEE single-precision floating point numbers.
|
|
This corresponds closely to the C/C++ type <SAMP>`float'</SAMP>.
|
|
|
|
<LI>
|
|
|
|
<A NAME="IDX22"></A>
|
|
Double floats, type <CODE>cl_DF</CODE>.
|
|
They have 1 sign bit, 11 exponent bits (including the exponent's sign),
|
|
and 53 mantissa bits (including the "hidden" bit).
|
|
In CLN, they are represented as IEEE double-precision floating point numbers.
|
|
This corresponds closely to the C/C++ type <SAMP>`double'</SAMP>.
|
|
|
|
<LI>
|
|
|
|
<A NAME="IDX23"></A>
|
|
Long floats, type <CODE>cl_LF</CODE>.
|
|
They have 1 sign bit, 32 exponent bits (including the exponent's sign),
|
|
and n mantissa bits (including the "hidden" bit), where n >= 64.
|
|
The precision of a long float is unlimited, but once created, a long float
|
|
has a fixed precision. (No "lazy recomputation".)
|
|
</UL>
|
|
|
|
<P>
|
|
Of course, computations with long floats are more expensive than those
|
|
with smaller floating-point formats.
|
|
|
|
|
|
<P>
|
|
CLN does not implement features like NaNs, denormalized numbers and
|
|
gradual underflow. If the exponent range of some floating-point type
|
|
is too limited for your application, choose another floating-point type
|
|
with larger exponent range.
|
|
|
|
|
|
<P>
|
|
<A NAME="IDX24"></A>
|
|
As a user of CLN, you can forget about the differences between the
|
|
four floating-point types and just declare all your floating-point
|
|
variables as being of type <CODE>cl_F</CODE>. This has the advantage that
|
|
when you change the precision of some computation (say, from <CODE>cl_DF</CODE>
|
|
to <CODE>cl_LF</CODE>), you don't have to change the code, only the precision
|
|
of the initial values. Also, many transcendental functions have been
|
|
declared as returning a <CODE>cl_F</CODE> when the argument is a <CODE>cl_F</CODE>,
|
|
but such declarations are missing for the types <CODE>cl_SF</CODE>, <CODE>cl_FF</CODE>,
|
|
<CODE>cl_DF</CODE>, <CODE>cl_LF</CODE>. (Such declarations would be wrong if
|
|
the floating point contagion rule happened to change in the future.)
|
|
|
|
|
|
|
|
|
|
<H2><A NAME="SEC14" HREF="cln_toc.html#TOC14">3.3 Complex numbers</A></H2>
|
|
<P>
|
|
<A NAME="IDX25"></A>
|
|
|
|
|
|
<P>
|
|
Complex numbers, as implemented by the class <CODE>cl_N</CODE>, have a real
|
|
part and an imaginary part, both real numbers. A complex number whose
|
|
imaginary part is the exact number <CODE>0</CODE> is automatically converted
|
|
to a real number.
|
|
|
|
|
|
<P>
|
|
Complex numbers can arise from real numbers alone, for example
|
|
through application of <CODE>sqrt</CODE> or transcendental functions.
|
|
|
|
|
|
|
|
|
|
<H2><A NAME="SEC15" HREF="cln_toc.html#TOC15">3.4 Conversions</A></H2>
|
|
<P>
|
|
<A NAME="IDX26"></A>
|
|
|
|
|
|
<P>
|
|
Conversions from any class to any its superclasses ("base classes" in
|
|
C++ terminology) is done automatically.
|
|
|
|
|
|
<P>
|
|
Conversions from the C built-in types <SAMP>`long'</SAMP> and <SAMP>`unsigned long'</SAMP>
|
|
are provided for the classes <CODE>cl_I</CODE>, <CODE>cl_RA</CODE>, <CODE>cl_R</CODE>,
|
|
<CODE>cl_N</CODE> and <CODE>cl_number</CODE>.
|
|
|
|
|
|
<P>
|
|
Conversions from the C built-in types <SAMP>`int'</SAMP> and <SAMP>`unsigned int'</SAMP>
|
|
are provided for the classes <CODE>cl_I</CODE>, <CODE>cl_RA</CODE>, <CODE>cl_R</CODE>,
|
|
<CODE>cl_N</CODE> and <CODE>cl_number</CODE>. However, these conversions emphasize
|
|
efficiency. Their range is therefore limited:
|
|
|
|
|
|
|
|
<UL>
|
|
<LI>
|
|
|
|
The conversion from <SAMP>`int'</SAMP> works only if the argument is < 2^29 and > -2^29.
|
|
<LI>
|
|
|
|
The conversion from <SAMP>`unsigned int'</SAMP> works only if the argument is < 2^29.
|
|
</UL>
|
|
|
|
<P>
|
|
In a declaration like <SAMP>`cl_I x = 10;'</SAMP> the C++ compiler is able to
|
|
do the conversion of <CODE>10</CODE> from <SAMP>`int'</SAMP> to <SAMP>`cl_I'</SAMP> at compile time
|
|
already. On the other hand, code like <SAMP>`cl_I x = 1000000000;'</SAMP> is
|
|
in error.
|
|
So, if you want to be sure that an <SAMP>`int'</SAMP> whose magnitude is not guaranteed
|
|
to be < 2^29 is correctly converted to a <SAMP>`cl_I'</SAMP>, first convert it to a
|
|
<SAMP>`long'</SAMP>. Similarly, if a large <SAMP>`unsigned int'</SAMP> is to be converted to a
|
|
<SAMP>`cl_I'</SAMP>, first convert it to an <SAMP>`unsigned long'</SAMP>.
|
|
|
|
|
|
<P>
|
|
Conversions from the C built-in type <SAMP>`float'</SAMP> are provided for the classes
|
|
<CODE>cl_FF</CODE>, <CODE>cl_F</CODE>, <CODE>cl_R</CODE>, <CODE>cl_N</CODE> and <CODE>cl_number</CODE>.
|
|
|
|
|
|
<P>
|
|
Conversions from the C built-in type <SAMP>`double'</SAMP> are provided for the classes
|
|
<CODE>cl_DF</CODE>, <CODE>cl_F</CODE>, <CODE>cl_R</CODE>, <CODE>cl_N</CODE> and <CODE>cl_number</CODE>.
|
|
|
|
|
|
<P>
|
|
Conversions from <SAMP>`const char *'</SAMP> are provided for the classes
|
|
<CODE>cl_I</CODE>, <CODE>cl_RA</CODE>,
|
|
<CODE>cl_SF</CODE>, <CODE>cl_FF</CODE>, <CODE>cl_DF</CODE>, <CODE>cl_LF</CODE>, <CODE>cl_F</CODE>,
|
|
<CODE>cl_R</CODE>, <CODE>cl_N</CODE>.
|
|
The easiest way to specify a value which is outside of the range of the
|
|
C++ built-in types is therefore to specify it as a string, like this:
|
|
<A NAME="IDX27"></A>
|
|
|
|
<PRE>
|
|
cl_I order_of_rubiks_cube_group = "43252003274489856000";
|
|
</PRE>
|
|
|
|
<P>
|
|
Note that this conversion is done at runtime, not at compile-time.
|
|
|
|
|
|
<P>
|
|
Conversions from <CODE>cl_I</CODE> to the C built-in types <SAMP>`int'</SAMP>,
|
|
<SAMP>`unsigned int'</SAMP>, <SAMP>`long'</SAMP>, <SAMP>`unsigned long'</SAMP> are provided through
|
|
the functions
|
|
|
|
|
|
<DL COMPACT>
|
|
|
|
<DT><CODE>int cl_I_to_int (const cl_I& x)</CODE>
|
|
<DD>
|
|
<A NAME="IDX28"></A>
|
|
<DT><CODE>unsigned int cl_I_to_uint (const cl_I& x)</CODE>
|
|
<DD>
|
|
<A NAME="IDX29"></A>
|
|
<DT><CODE>long cl_I_to_long (const cl_I& x)</CODE>
|
|
<DD>
|
|
<A NAME="IDX30"></A>
|
|
<DT><CODE>unsigned long cl_I_to_ulong (const cl_I& x)</CODE>
|
|
<DD>
|
|
<A NAME="IDX31"></A>
|
|
Returns <CODE>x</CODE> as element of the C type <VAR>ctype</VAR>. If <CODE>x</CODE> is not
|
|
representable in the range of <VAR>ctype</VAR>, a runtime error occurs.
|
|
</DL>
|
|
|
|
<P>
|
|
Conversions from the classes <CODE>cl_I</CODE>, <CODE>cl_RA</CODE>,
|
|
<CODE>cl_SF</CODE>, <CODE>cl_FF</CODE>, <CODE>cl_DF</CODE>, <CODE>cl_LF</CODE>, <CODE>cl_F</CODE> and
|
|
<CODE>cl_R</CODE>
|
|
to the C built-in types <SAMP>`float'</SAMP> and <SAMP>`double'</SAMP> are provided through
|
|
the functions
|
|
|
|
|
|
<DL COMPACT>
|
|
|
|
<DT><CODE>float cl_float_approx (const <VAR>type</VAR>& x)</CODE>
|
|
<DD>
|
|
<A NAME="IDX32"></A>
|
|
<DT><CODE>double cl_double_approx (const <VAR>type</VAR>& x)</CODE>
|
|
<DD>
|
|
<A NAME="IDX33"></A>
|
|
Returns an approximation of <CODE>x</CODE> of C type <VAR>ctype</VAR>.
|
|
If <CODE>abs(x)</CODE> is too close to 0 (underflow), 0 is returned.
|
|
If <CODE>abs(x)</CODE> is too large (overflow), an IEEE infinity is returned.
|
|
</DL>
|
|
|
|
<P>
|
|
Conversions from any class to any of its subclasses ("derived classes" in
|
|
C++ terminology) are not provided. Instead, you can assert and check
|
|
that a value belongs to a certain subclass, and return it as element of that
|
|
class, using the <SAMP>`As'</SAMP> and <SAMP>`The'</SAMP> macros.
|
|
<A NAME="IDX34"></A>
|
|
<CODE>As(<VAR>type</VAR>)(<VAR>value</VAR>)</CODE> checks that <VAR>value</VAR> belongs to
|
|
<VAR>type</VAR> and returns it as such.
|
|
<A NAME="IDX35"></A>
|
|
<CODE>The(<VAR>type</VAR>)(<VAR>value</VAR>)</CODE> assumes that <VAR>value</VAR> belongs to
|
|
<VAR>type</VAR> and returns it as such. It is your responsibility to ensure
|
|
that this assumption is valid.
|
|
Example:
|
|
|
|
|
|
|
|
<PRE>
|
|
cl_I x = ...;
|
|
if (!(x >= 0)) abort();
|
|
cl_I ten_x = The(cl_I)(expt(10,x)); // If x >= 0, 10^x is an integer.
|
|
// In general, it would be a rational number.
|
|
</PRE>
|
|
|
|
<P><HR><P>
|
|
Go to the <A HREF="cln_1.html">first</A>, <A HREF="cln_2.html">previous</A>, <A HREF="cln_4.html">next</A>, <A HREF="cln_13.html">last</A> section, <A HREF="cln_toc.html">table of contents</A>.
|
|
</BODY>
|
|
</HTML>
|