You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
251 lines
12 KiB
HTML
251 lines
12 KiB
HTML
4 years ago
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html>
|
||
|
<!-- This manual describes how to install and use the GNU multiple precision
|
||
|
arithmetic library, version 6.1.0.
|
||
|
|
||
|
Copyright 1991, 1993-2015 Free Software Foundation, Inc.
|
||
|
|
||
|
Permission is granted to copy, distribute and/or modify this document under
|
||
|
the terms of the GNU Free Documentation License, Version 1.3 or any later
|
||
|
version published by the Free Software Foundation; with no Invariant Sections,
|
||
|
with the Front-Cover Texts being "A GNU Manual", and with the Back-Cover
|
||
|
Texts being "You have freedom to copy and modify this GNU Manual, like GNU
|
||
|
software". A copy of the license is included in
|
||
|
GNU Free Documentation License. -->
|
||
|
<!-- Created by GNU Texinfo 6.4, http://www.gnu.org/software/texinfo/ -->
|
||
|
<head>
|
||
|
<title>Float Internals (GNU MP 6.1.0)</title>
|
||
|
|
||
|
<meta name="description" content="How to install and use the GNU multiple precision arithmetic library, version 6.1.0.">
|
||
|
<meta name="keywords" content="Float Internals (GNU MP 6.1.0)">
|
||
|
<meta name="resource-type" content="document">
|
||
|
<meta name="distribution" content="global">
|
||
|
<meta name="Generator" content="makeinfo">
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||
|
<link href="index.html#Top" rel="start" title="Top">
|
||
|
<link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index">
|
||
|
<link href="Internals.html#Internals" rel="up" title="Internals">
|
||
|
<link href="Raw-Output-Internals.html#Raw-Output-Internals" rel="next" title="Raw Output Internals">
|
||
|
<link href="Rational-Internals.html#Rational-Internals" rel="prev" title="Rational Internals">
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
a.summary-letter {text-decoration: none}
|
||
|
blockquote.indentedblock {margin-right: 0em}
|
||
|
blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
|
||
|
blockquote.smallquotation {font-size: smaller}
|
||
|
div.display {margin-left: 3.2em}
|
||
|
div.example {margin-left: 3.2em}
|
||
|
div.lisp {margin-left: 3.2em}
|
||
|
div.smalldisplay {margin-left: 3.2em}
|
||
|
div.smallexample {margin-left: 3.2em}
|
||
|
div.smalllisp {margin-left: 3.2em}
|
||
|
kbd {font-style: oblique}
|
||
|
pre.display {font-family: inherit}
|
||
|
pre.format {font-family: inherit}
|
||
|
pre.menu-comment {font-family: serif}
|
||
|
pre.menu-preformatted {font-family: serif}
|
||
|
pre.smalldisplay {font-family: inherit; font-size: smaller}
|
||
|
pre.smallexample {font-size: smaller}
|
||
|
pre.smallformat {font-family: inherit; font-size: smaller}
|
||
|
pre.smalllisp {font-size: smaller}
|
||
|
span.nolinebreak {white-space: nowrap}
|
||
|
span.roman {font-family: initial; font-weight: normal}
|
||
|
span.sansserif {font-family: sans-serif; font-weight: normal}
|
||
|
ul.no-bullet {list-style: none}
|
||
|
-->
|
||
|
</style>
|
||
|
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body lang="en">
|
||
|
<a name="Float-Internals"></a>
|
||
|
<div class="header">
|
||
|
<p>
|
||
|
Next: <a href="Raw-Output-Internals.html#Raw-Output-Internals" accesskey="n" rel="next">Raw Output Internals</a>, Previous: <a href="Rational-Internals.html#Rational-Internals" accesskey="p" rel="prev">Rational Internals</a>, Up: <a href="Internals.html#Internals" accesskey="u" rel="up">Internals</a> [<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<hr>
|
||
|
<a name="Float-Internals-1"></a>
|
||
|
<h3 class="section">16.3 Float Internals</h3>
|
||
|
<a name="index-Float-internals"></a>
|
||
|
|
||
|
<p>Efficient calculation is the primary aim of GMP floats and the use of whole
|
||
|
limbs and simple rounding facilitates this.
|
||
|
</p>
|
||
|
<p><code>mpf_t</code> floats have a variable precision mantissa and a single machine
|
||
|
word signed exponent. The mantissa is represented using sign and magnitude.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example"> most least
|
||
|
significant significant
|
||
|
limb limb
|
||
|
|
||
|
_mp_d
|
||
|
|---- _mp_exp ---> |
|
||
|
_____ _____ _____ _____ _____
|
||
|
|_____|_____|_____|_____|_____|
|
||
|
. <------------ radix point
|
||
|
|
||
|
<-------- _mp_size --------->
|
||
|
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The fields are as follows.
|
||
|
</p>
|
||
|
<dl compact="compact">
|
||
|
<dt><code>_mp_size</code></dt>
|
||
|
<dd><p>The number of limbs currently in use, or the negative of that when
|
||
|
representing a negative value. Zero is represented by <code>_mp_size</code> and
|
||
|
<code>_mp_exp</code> both set to zero, and in that case the <code>_mp_d</code> data is
|
||
|
unused. (In the future <code>_mp_exp</code> might be undefined when representing
|
||
|
zero.)
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt><code>_mp_prec</code></dt>
|
||
|
<dd><p>The precision of the mantissa, in limbs. In any calculation the aim is to
|
||
|
produce <code>_mp_prec</code> limbs of result (the most significant being non-zero).
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt><code>_mp_d</code></dt>
|
||
|
<dd><p>A pointer to the array of limbs which is the absolute value of the mantissa.
|
||
|
These are stored “little endian” as per the <code>mpn</code> functions, so
|
||
|
<code>_mp_d[0]</code> is the least significant limb and
|
||
|
<code>_mp_d[ABS(_mp_size)-1]</code> the most significant.
|
||
|
</p>
|
||
|
<p>The most significant limb is always non-zero, but there are no other
|
||
|
restrictions on its value, in particular the highest 1 bit can be anywhere
|
||
|
within the limb.
|
||
|
</p>
|
||
|
<p><code>_mp_prec+1</code> limbs are allocated to <code>_mp_d</code>, the extra limb being
|
||
|
for convenience (see below). There are no reallocations during a calculation,
|
||
|
only in a change of precision with <code>mpf_set_prec</code>.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt><code>_mp_exp</code></dt>
|
||
|
<dd><p>The exponent, in limbs, determining the location of the implied radix point.
|
||
|
Zero means the radix point is just above the most significant limb. Positive
|
||
|
values mean a radix point offset towards the lower limbs and hence a value
|
||
|
<em>>= 1</em>, as for example in the diagram above. Negative exponents mean
|
||
|
a radix point further above the highest limb.
|
||
|
</p>
|
||
|
<p>Naturally the exponent can be any value, it doesn’t have to fall within the
|
||
|
limbs as the diagram shows, it can be a long way above or a long way below.
|
||
|
Limbs other than those included in the <code>{_mp_d,_mp_size}</code> data
|
||
|
are treated as zero.
|
||
|
</p></dd>
|
||
|
</dl>
|
||
|
|
||
|
<p>The <code>_mp_size</code> and <code>_mp_prec</code> fields are <code>int</code>, although the
|
||
|
<code>mp_size_t</code> type is usually a <code>long</code>. The <code>_mp_exp</code> field is
|
||
|
usually <code>long</code>. This is done to make some fields just 32 bits on some 64
|
||
|
bits systems, thereby saving a few bytes of data space but still providing
|
||
|
plenty of precision and a very large range.
|
||
|
</p>
|
||
|
|
||
|
<br>
|
||
|
<p>The following various points should be noted.
|
||
|
</p>
|
||
|
<dl compact="compact">
|
||
|
<dt>Low Zeros</dt>
|
||
|
<dd><p>The least significant limbs <code>_mp_d[0]</code> etc can be zero, though such low
|
||
|
zeros can always be ignored. Routines likely to produce low zeros check and
|
||
|
avoid them to save time in subsequent calculations, but for most routines
|
||
|
they’re quite unlikely and aren’t checked.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Mantissa Size Range</dt>
|
||
|
<dd><p>The <code>_mp_size</code> count of limbs in use can be less than <code>_mp_prec</code> if
|
||
|
the value can be represented in less. This means low precision values or
|
||
|
small integers stored in a high precision <code>mpf_t</code> can still be operated
|
||
|
on efficiently.
|
||
|
</p>
|
||
|
<p><code>_mp_size</code> can also be greater than <code>_mp_prec</code>. Firstly a value is
|
||
|
allowed to use all of the <code>_mp_prec+1</code> limbs available at <code>_mp_d</code>,
|
||
|
and secondly when <code>mpf_set_prec_raw</code> lowers <code>_mp_prec</code> it leaves
|
||
|
<code>_mp_size</code> unchanged and so the size can be arbitrarily bigger than
|
||
|
<code>_mp_prec</code>.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Rounding</dt>
|
||
|
<dd><p>All rounding is done on limb boundaries. Calculating <code>_mp_prec</code> limbs
|
||
|
with the high non-zero will ensure the application requested minimum precision
|
||
|
is obtained.
|
||
|
</p>
|
||
|
<p>The use of simple “trunc” rounding towards zero is efficient, since there’s
|
||
|
no need to examine extra limbs and increment or decrement.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Bit Shifts</dt>
|
||
|
<dd><p>Since the exponent is in limbs, there are no bit shifts in basic operations
|
||
|
like <code>mpf_add</code> and <code>mpf_mul</code>. When differing exponents are
|
||
|
encountered all that’s needed is to adjust pointers to line up the relevant
|
||
|
limbs.
|
||
|
</p>
|
||
|
<p>Of course <code>mpf_mul_2exp</code> and <code>mpf_div_2exp</code> will require bit shifts,
|
||
|
but the choice is between an exponent in limbs which requires shifts there, or
|
||
|
one in bits which requires them almost everywhere else.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Use of <code>_mp_prec+1</code> Limbs</dt>
|
||
|
<dd><p>The extra limb on <code>_mp_d</code> (<code>_mp_prec+1</code> rather than just
|
||
|
<code>_mp_prec</code>) helps when an <code>mpf</code> routine might get a carry from its
|
||
|
operation. <code>mpf_add</code> for instance will do an <code>mpn_add</code> of
|
||
|
<code>_mp_prec</code> limbs. If there’s no carry then that’s the result, but if
|
||
|
there is a carry then it’s stored in the extra limb of space and
|
||
|
<code>_mp_size</code> becomes <code>_mp_prec+1</code>.
|
||
|
</p>
|
||
|
<p>Whenever <code>_mp_prec+1</code> limbs are held in a variable, the low limb is not
|
||
|
needed for the intended precision, only the <code>_mp_prec</code> high limbs. But
|
||
|
zeroing it out or moving the rest down is unnecessary. Subsequent routines
|
||
|
reading the value will simply take the high limbs they need, and this will be
|
||
|
<code>_mp_prec</code> if their target has that same precision. This is no more than
|
||
|
a pointer adjustment, and must be checked anyway since the destination
|
||
|
precision can be different from the sources.
|
||
|
</p>
|
||
|
<p>Copy functions like <code>mpf_set</code> will retain a full <code>_mp_prec+1</code> limbs
|
||
|
if available. This ensures that a variable which has <code>_mp_size</code> equal to
|
||
|
<code>_mp_prec+1</code> will get its full exact value copied. Strictly speaking
|
||
|
this is unnecessary since only <code>_mp_prec</code> limbs are needed for the
|
||
|
application’s requested precision, but it’s considered that an <code>mpf_set</code>
|
||
|
from one variable into another of the same precision ought to produce an exact
|
||
|
copy.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Application Precisions</dt>
|
||
|
<dd><p><code>__GMPF_BITS_TO_PREC</code> converts an application requested precision to an
|
||
|
<code>_mp_prec</code>. The value in bits is rounded up to a whole limb then an
|
||
|
extra limb is added since the most significant limb of <code>_mp_d</code> is only
|
||
|
non-zero and therefore might contain only one bit.
|
||
|
</p>
|
||
|
<p><code>__GMPF_PREC_TO_BITS</code> does the reverse conversion, and removes the extra
|
||
|
limb from <code>_mp_prec</code> before converting to bits. The net effect of
|
||
|
reading back with <code>mpf_get_prec</code> is simply the precision rounded up to a
|
||
|
multiple of <code>mp_bits_per_limb</code>.
|
||
|
</p>
|
||
|
<p>Note that the extra limb added here for the high only being non-zero is in
|
||
|
addition to the extra limb allocated to <code>_mp_d</code>. For example with a
|
||
|
32-bit limb, an application request for 250 bits will be rounded up to 8
|
||
|
limbs, then an extra added for the high being only non-zero, giving an
|
||
|
<code>_mp_prec</code> of 9. <code>_mp_d</code> then gets 10 limbs allocated. Reading
|
||
|
back with <code>mpf_get_prec</code> will take <code>_mp_prec</code> subtract 1 limb and
|
||
|
multiply by 32, giving 256 bits.
|
||
|
</p>
|
||
|
<p>Strictly speaking, the fact the high limb has at least one bit means that a
|
||
|
float with, say, 3 limbs of 32-bits each will be holding at least 65 bits, but
|
||
|
for the purposes of <code>mpf_t</code> it’s considered simply to be 64 bits, a nice
|
||
|
multiple of the limb size.
|
||
|
</p></dd>
|
||
|
</dl>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<div class="header">
|
||
|
<p>
|
||
|
Next: <a href="Raw-Output-Internals.html#Raw-Output-Internals" accesskey="n" rel="next">Raw Output Internals</a>, Previous: <a href="Rational-Internals.html#Rational-Internals" accesskey="p" rel="prev">Rational Internals</a>, Up: <a href="Internals.html#Internals" accesskey="u" rel="up">Internals</a> [<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|