1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 08:34:22 +03:00
inform7/docs/kinds-module/2-sav.html
2020-04-07 01:06:09 +01:00

1155 lines
147 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/fv</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '2/sav' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">kinds</a></li><li><a href="index.html#2">Chapter 2: Kinds</a></li><li><b>Scaled Arithmetic Values</b></li></ul><p class="purpose">To manage the scalings and offsets used when storing arithmetic values at run-time, and/or when using scaled units to refer to them.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP6">&#167;6. Logging</a></li><li><a href="#SP7">&#167;7. Definition</a></li><li><a href="#SP10">&#167;10. Enlarging and contracting</a></li><li><a href="#SP11">&#167;11. Using scalings</a></li><li><a href="#SP14">&#167;14. Scaled arithmetic at compile-time</a></li><li><a href="#SP17">&#167;17. Scaled arithmetic at run-time</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Some literal patterns allow us to give values using scaled units. For
example, "1 g" and "1 kg" might both define constant values of the same
kind, but the "1" is read differently in the two cases: it's worth 1000
times as much in the second case.
</p>
<p class="inwebparagraph">A "scaling transformation" defines the relationship between the number
as written and the number stored at runtime. The conversion between the
two is always a linear function: a number written as <code class="display"><span class="extract">x kg</span></code> is stored
as <code class="display"><span class="extract">M*x + O</span></code> at run-time for constants <code class="display"><span class="extract">M</span></code> and <code class="display"><span class="extract">O</span></code>, the "multiplier"
and "offset". <code class="display"><span class="extract">M</span></code> must be positive, <code class="display"><span class="extract">O</span></code> must be positive or zero.
</p>
<p class="inwebparagraph">Units typically have a range of different literal patterns with different
scalings: for example, "1 mm", "1 cm", "1 m", "1 km". One of these patterns
is designated as the "benchmark": in the case of length, probably "1 m".
This is the one we think of abstractly as the natural notation to use
when we don't know that the value is particularly large or small.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>We have to implement all of this twice, in subtly different ways, to
cope with the fact that some units use integer arithmetic and others
use real.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) Real units are easier. A value of <code class="display"><span class="extract">1.0</span></code> stored at run-time equals
1 benchmark unit: in our length example, 1 m. Thus the <code class="display"><span class="extract">M</span></code> value for the
benchmark scaling is always 1.0.
</li></ul>
<ul class="items"><li>(b) Integer units are harder. If we stored 1 m as the integer 1, we
would be unable to express any distance smaller than that, and "1 cm"
or "1 mm" would vanish completely. Instead we scale so that the value
1 stored at run-time equals 1 unit of our smallest scale: in the length
example, 1 mm. The <code class="display"><span class="extract">M</span></code> value for the benchmark is now usually not 1 &mdash;
in this example, it's 1000, because one benchmark unit (1 m) is stored
as the integer 1000.
</li></ul>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The benchmark <code class="display"><span class="extract">M</span></code> has a special significance because it affects the
result of arithmetic (unless it equals 1). For example, suppose we
multiply 2 m by 3 m to get 6 square meters, and suppose the benchmark
<code class="display"><span class="extract">M</span></code> is 1000 for both length and area. Then the 2 m and 3 m are stored
as 2000 and 3000. Simply multiplying those as integers gives 6000000,
but that corresponds to 6000 square meters, not 6. So the result of the
multiplication must be rescaled to give the right answer.
</p>
<p class="inwebparagraph">Since, as noted above, benchmark <code class="display"><span class="extract">M</span></code> is always 1 for real values, there's
no need for rescaling with real arithmetic.
</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Scalings are defined one at a time, and usually in terms of each other.
We can't know the values of <code class="display"><span class="extract">M</span></code> they end up with until all have been
defined.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">LP_SCALED_UP</span><span class="plain"> </span><span class="constant">1</span>
<span class="definitionkeyword">define</span> <span class="constant">LP_SCALED_DOWN</span><span class="plain"> -1</span>
<span class="definitionkeyword">define</span> <span class="constant">LP_SCALED_AT</span><span class="plain"> </span><span class="constant">2</span>
</pre>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">scaling_transformation</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">use_integer_scaling</span><span class="plain">; </span><span class="comment">or if not, use real</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">int_O</span><span class="plain">; </span><span class="comment">the O value described above, if integers used</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">int_M</span><span class="plain">; </span><span class="comment">the M value described above</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">real_O</span><span class="plain">; </span><span class="comment">the O value described above, if real numbers used</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">real_M</span><span class="plain">; </span><span class="comment">the M value described above</span>
<span class="comment">used only in the definition process</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">scaling_mode</span><span class="plain">; </span><span class="comment">one of the <code class="display"><span class="extract">LP_SCALED_*</span></code> constants</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">int_scalar</span><span class="plain">; </span><span class="comment">whichever of these is relevant according to the integer/real mode</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">real_scalar</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">scaling_transformation</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure scaling_transformation is private to this section.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Logging. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::describe</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"scaling: x units --&gt; "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">)</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d x + %x stored at runtime (int)"</span><span class="plain">, </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain">, </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_O</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%g x + %g stored at runtime (real)"</span><span class="plain">, </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain">, </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_O</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="identifier">scaling_mode</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LP_SCALED_UP:</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" (defined as benchmark * "</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LP_SCALED_DOWN:</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" (defined as benchmark / "</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LP_SCALED_AT:</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" (defined as scaled at "</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d)"</span><span class="plain">, </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_scalar</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%g)"</span><span class="plain">, </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_scalar</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::describe appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Definition. </b>A new scaling is given with a scale factor either pegging it absolutely, or
relative to the benchmark. At initial definition time, we don't calculate <code class="display"><span class="extract">M</span></code>:
we just take notes for later.
</p>
<pre class="display">
<span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::new</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">integer_valued</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">scaled</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">int_s</span><span class="plain">, </span><span class="reserved">double</span><span class="plain"> </span><span class="identifier">real_s</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">offset</span><span class="plain">, </span><span class="reserved">double</span><span class="plain"> </span><span class="identifier">real_offset</span><span class="plain">) {</span>
<span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain"> = </span><span class="identifier">integer_valued</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">int_O</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_O</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">.0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">integer_valued</span><span class="plain">) </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_O</span><span class="plain"> = </span><span class="identifier">offset</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_O</span><span class="plain"> = (</span><span class="reserved">double</span><span class="plain">) </span><span class="identifier">real_offset</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">.0;</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">scaling_mode</span><span class="plain"> = </span><span class="identifier">scaled</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">int_scalar</span><span class="plain"> = </span><span class="identifier">int_s</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">real_scalar</span><span class="plain"> = </span><span class="identifier">real_s</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::new appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>Soon after definition, we may realise that real arithmetic is needed after
all, even though we previously expected it to use integers. So:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::convert_to_real</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> *</span><span class="identifier">sc</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_O</span><span class="plain"> = (</span><span class="reserved">double</span><span class="plain">) </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_O</span><span class="plain">; </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_O</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_M</span><span class="plain"> = (</span><span class="reserved">double</span><span class="plain">) </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_M</span><span class="plain">; </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_M</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_scalar</span><span class="plain"> = (</span><span class="reserved">double</span><span class="plain">) </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_scalar</span><span class="plain">; </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_scalar</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">use_integer_scaling</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::convert_to_real appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Each new scaling in turn is added to the list of those in use for a given
kind. For example, when the "1 km" scaling is added to those for lengths,
perhaps "1 cm" and "1 m" (the benchmark) already exist, but "1 mm" doesn't.
We call the following routine to calculate a suitable <code class="display"><span class="extract">M</span></code> for the scaling.
It returns a value which is either <code class="display"><span class="extract">-1</span></code>, or else a scale factor by which
to increase the <code class="display"><span class="extract">M</span></code> values of everything else in the list.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::determine_M</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> *</span><span class="identifier">sc</span><span class="plain">,</span>
<span class="reserved">scaling_transformation</span><span class="plain"> *</span><span class="identifier">benchmark_sc</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">first</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">equiv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">alt</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rescale_the_others_by_this</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="comment">in effect, don't</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">first</span><span class="plain">) </span>&lt;<span class="cwebmacro">Determine M for the first scaling of the list</span> <span class="cwebmacronumber">9.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Determine M for a subsequent scaling of the list</span> <span class="cwebmacronumber">9.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rescale_the_others_by_this</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::determine_M appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP9_1"></a><b>&#167;9.1. </b>This is the easy case &mdash; there's no list yet, and no benchmark yet. The <code class="display"><span class="extract">M</span></code>
value will usually therefore be 1, unless the source text explicitly asked
for it to be something else:
</p>
<blockquote>
<p>1m specifies a length scaled at 10000.</p>
</blockquote>
<p class="inwebparagraph">in which case, of course, <code class="display"><span class="extract">M</span></code> is 10000. Since there's no benchmark yet, it
must be a problem message if the unit is defined scaled up or down from the
benchmark; and similarly if the new notation is claimed to be equivalent to
some existing notation, in which case the <code class="display"><span class="extract">equiv</span></code> flag is set.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Determine M for the first scaling of the list</span> <span class="cwebmacronumber">9.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="identifier">int_scalar</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">) || (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_scalar</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">.0)) &amp;&amp;</span>
<span class="plain">((</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">scaling_mode</span><span class="plain"> == </span><span class="constant">LP_SCALED_UP</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">scaling_mode</span><span class="plain"> == </span><span class="constant">LP_SCALED_DOWN</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">equiv</span><span class="plain">) ||</span>
<span class="plain">((</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">scaling_mode</span><span class="plain"> == </span><span class="constant">LP_SCALED_AT</span><span class="plain">) &amp;&amp; (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">use_integer_scaling</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">))))</span>
<span class="functiontext">Kinds::problem_handler</span><span class="plain">(</span><span class="constant">LPCantScaleYet_KINDERROR</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_M</span><span class="plain"> = </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_scalar</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_2"></a><b>&#167;9.2. </b>The harder case, when some scalings already exist for this kind. Firstly,
you can't create an alternative set of scalings (e.g. Imperial units such
as feet and inches) with its own absolute scale factor, because the existing
scalings (metric units such as mm, km, etc.) already have their <code class="display"><span class="extract">M</span></code> value.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Determine M for a subsequent scaling of the list</span> <span class="cwebmacronumber">9.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="identifier">int_scalar</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">) || (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_scalar</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">.0)) &amp;&amp;</span>
<span class="plain">((</span><span class="identifier">alt</span><span class="plain">) &amp;&amp; (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">scaling_mode</span><span class="plain"> == </span><span class="constant">LP_SCALED_AT</span><span class="plain">)))</span>
<span class="functiontext">Kinds::problem_handler</span><span class="plain">(</span><span class="constant">LPCantScaleTwice_KINDERROR</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">equiv</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Calculate the multiplier for this equivalent scaling</span> <span class="cwebmacronumber">9.2.1</span>&gt;
<span class="reserved">else</span>
&lt;<span class="cwebmacro">Calculate the multiplier for the LP relative to the benchmark</span> <span class="cwebmacronumber">9.2.2</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_2_1"></a><b>&#167;9.2.1. </b>An equivalent unit exactly specifies its <code class="display"><span class="extract">M</span></code>-value. For example:
</p>
<blockquote>
<p>1 pencil specifies a length equivalent to 18cm.</p>
</blockquote>
<p class="inwebparagraph">What happens here is that "18cm" is parsed and turned not into 18, but into
the "1 cm" scaling applied to 18, and that's the value in our scalar,
which then becomes <code class="display"><span class="extract">M</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Calculate the multiplier for this equivalent scaling</span> <span class="cwebmacronumber">9.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">use_integer_scaling</span><span class="plain">)</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_M</span><span class="plain"> = </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_scalar</span><span class="plain">;</span>
<span class="reserved">else</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_M</span><span class="plain"> = </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_scalar</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_2">&#167;9.2</a>.</p>
<p class="inwebparagraph"><a id="SP9_2_2"></a><b>&#167;9.2.2. </b>Finally the trickiest case. We calculate <code class="display"><span class="extract">M</span></code> based on scaling the benchmark
either up or down.
</p>
<p class="inwebparagraph">Scaling up by <code class="display"><span class="extract">k</span></code> is no problem: the <code class="display"><span class="extract">M</span></code> value is just <code class="display"><span class="extract">k</span></code> times the benchmark
<code class="display"><span class="extract">M</span></code>, which we call <code class="display"><span class="extract">B</span></code>.
</p>
<p class="inwebparagraph">Scaling down might look similar: we want <code class="display"><span class="extract">M = B/k</span></code>. But in integer arithmetic
<code class="display"><span class="extract">k</span></code> probably doesn't divide <code class="display"><span class="extract">B</span></code>, and extreme cases frequently occur: for
example, where <code class="display"><span class="extract">k</span></code> is 1000 and <code class="display"><span class="extract">B</span></code> is 1.
</p>
<p class="inwebparagraph">We get around this by increasing every <code class="display"><span class="extract">M</span></code>-value in the list by a factor of:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">k / gcd(B, k)</span>
</pre>
<p class="inwebparagraph">Note that <code class="display"><span class="extract">B</span></code> also increases in this process, and in fact becomes
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">Bk / gcd(B, k)</span>
</pre>
<p class="inwebparagraph">which is the smallest multiple of <code class="display"><span class="extract">B</span></code> which has <code class="display"><span class="extract">k</span></code> as a factor. (If in fact
<code class="display"><span class="extract">k</span></code> always divided <code class="display"><span class="extract">B</span></code>, then the scale multiple is 1 and no change is made.)
That means that the new value of <code class="display"><span class="extract">B</span></code> divided by <code class="display"><span class="extract">k</span></code> will be
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">B / gcd(B, k)</span>
</pre>
<p class="inwebparagraph">so this is what we set <code class="display"><span class="extract">M</span></code> to.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Calculate the multiplier for the LP relative to the benchmark</span> <span class="cwebmacronumber">9.2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">benchmark_sc</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no benchmark for comparison"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">scaling_mode</span><span class="plain"> == </span><span class="constant">LP_SCALED_DOWN</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">B</span><span class="plain"> = </span><span class="identifier">benchmark_sc</span><span class="plain">-&gt;</span><span class="element">int_M</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> = </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_scalar</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">g</span><span class="plain"> = </span><span class="functiontext">Kinds::Dimensions::gcd</span><span class="plain">(</span><span class="identifier">B</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">);</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_M</span><span class="plain"> = </span><span class="identifier">B</span><span class="plain">/</span><span class="identifier">g</span><span class="plain">;</span>
<span class="identifier">rescale_the_others_by_this</span><span class="plain"> = </span><span class="identifier">k</span><span class="plain">/</span><span class="identifier">g</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">B</span><span class="plain"> = </span><span class="identifier">benchmark_sc</span><span class="plain">-&gt;</span><span class="element">real_M</span><span class="plain">;</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> = </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_scalar</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_M</span><span class="plain"> = </span><span class="identifier">B</span><span class="plain">/</span><span class="identifier">k</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">scaling_mode</span><span class="plain"> == </span><span class="constant">LP_SCALED_UP</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">B</span><span class="plain"> = </span><span class="identifier">benchmark_sc</span><span class="plain">-&gt;</span><span class="element">int_M</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> = </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_scalar</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">int_M</span><span class="plain"> = </span><span class="identifier">B</span><span class="plain">*</span><span class="identifier">k</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">B</span><span class="plain"> = </span><span class="identifier">benchmark_sc</span><span class="plain">-&gt;</span><span class="element">real_M</span><span class="plain">;</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> = </span><span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_scalar</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">-&gt;</span><span class="element">real_M</span><span class="plain"> = </span><span class="identifier">B</span><span class="plain">*</span><span class="identifier">k</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_2">&#167;9.2</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Enlarging and contracting. </b>Note that the offset values <code class="display"><span class="extract">O</span></code> are not affected here. The idea is this:
suppose we have a unit such as temperature, and have defined centigrade as
a scaling with offset 273. Then suppose we want a unit equal to 0.1 of a
degree centigrade: we want to scale down C by 10, but preserve offset 273,
so that the value "1 deciC" (or whatever) is 273.1 degrees, not 27.4.
(In practice, and wisely, scientists never scale units with offsets, so
this seldom arises.)
</p>
<pre class="display">
<span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::enlarge</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> *= </span><span class="identifier">F</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain"> *= </span><span class="identifier">F</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::contract</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">loses_accuracy</span><span class="plain">) {</span>
<span class="plain">*</span><span class="identifier">loses_accuracy</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> % </span><span class="identifier">F</span><span class="plain"> != </span><span class="constant">0</span><span class="plain">) *</span><span class="identifier">loses_accuracy</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> /= </span><span class="identifier">F</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain"> /= </span><span class="identifier">F</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::enlarge appears nowhere else.</p>
<p class="endnote">The function Kinds::Scalings::contract appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Using scalings. </b>First, here's a <code class="display"><span class="extract">strcmp</span></code>-like routine to report which scaling is smaller
out of two; it's used for sorting scalings into ascending order of magnitude.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::compare</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">, </span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">B</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain"> != </span><span class="identifier">B</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">)</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"scalings incomparable"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> &gt; </span><span class="identifier">B</span><span class="plain">.</span><span class="element">int_M</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> &lt; </span><span class="identifier">B</span><span class="plain">.</span><span class="element">int_M</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">int_O</span><span class="plain"> &gt; </span><span class="identifier">B</span><span class="plain">.</span><span class="element">int_O</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">int_O</span><span class="plain"> &lt; </span><span class="identifier">B</span><span class="plain">.</span><span class="element">int_O</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">real_M</span><span class="plain"> &gt; </span><span class="identifier">B</span><span class="plain">.</span><span class="element">real_M</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">real_M</span><span class="plain"> &lt; </span><span class="identifier">B</span><span class="plain">.</span><span class="element">real_M</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">real_O</span><span class="plain"> &gt; </span><span class="identifier">B</span><span class="plain">.</span><span class="element">real_O</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain">.</span><span class="element">real_O</span><span class="plain"> &lt; </span><span class="identifier">B</span><span class="plain">.</span><span class="element">real_O</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::compare appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>Second, the following returns <code class="display"><span class="extract">M</span></code> unless we're in real mode, in which case it
returns 1.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::get_integer_multiplier</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">.</span><span class="identifier">int_M</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::get_integer_multiplier appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>Finally, this simply detects the presence of a scale factor, real or integer:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::involves_scale_change</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">.0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::involves_scale_change appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Scaled arithmetic at compile-time. </b>The "quantum" of a scaling is the run-time value corresponding to 1 unit:
for example, for kilometers, it's the run-time value which "1 km" translates
into.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::quantum</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain">) </span><span class="functiontext">Kinds::Scalings::quanta_to_value</span><span class="plain">(</span><span class="identifier">sc</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">double</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::real_quantum</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::real_quanta_to_value</span><span class="plain">(</span><span class="identifier">sc</span><span class="plain">, </span><span class="constant">1</span><span class="plain">.0);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::quantum is used in <a href="#SP20">&#167;20</a>.</p>
<p class="endnote">The function Kinds::Scalings::real_quantum is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>More generally, the following takes a number of quanta and turns it into
the run-time value that stores as:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::quanta_to_value</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">q</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">q</span><span class="plain">*</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> + </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_O</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">double</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::real_quanta_to_value</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">, </span><span class="reserved">double</span><span class="plain"> </span><span class="identifier">q</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">q</span><span class="plain">*</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain"> + </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_O</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::quanta_to_value is used in <a href="#SP14">&#167;14</a>.</p>
<p class="endnote">The function Kinds::Scalings::real_quanta_to_value is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>In integer arithmetic, the inverse of this function won't generally
exist, since division can't be performed exactly. The following is the
best we can do.
</p>
<p class="inwebparagraph">So consider the run-time value <code class="display"><span class="extract">v</span></code>, and let's try to express it as a
whole number of quanta plus a fractional remainder. For example, if the
scaling is for "1 m", with offset 0 and multiplier 1000, then the value
<code class="display"><span class="extract">v = 2643</span></code> produces 2 quanta and remainder 643/1000ths.
</p>
<p class="inwebparagraph">In real arithmetic, on the other hand, the inverse straightforwardly exists.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::value_to_quanta</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">v</span><span class="plain">, </span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">r</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"inversion unimplemented"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">r</span><span class="plain">) *</span><span class="identifier">r</span><span class="plain"> = (</span><span class="identifier">v</span><span class="plain"> - </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_O</span><span class="plain">) % (</span><span class="identifier">sc</span><span class="plain">.</span><span class="identifier">int_M</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">q</span><span class="plain">) *</span><span class="identifier">q</span><span class="plain"> = (</span><span class="identifier">v</span><span class="plain"> - </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_O</span><span class="plain">) / (</span><span class="identifier">sc</span><span class="plain">.</span><span class="identifier">int_M</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">double</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::real_value_to_quanta</span><span class="plain">(</span><span class="reserved">double</span><span class="plain"> </span><span class="identifier">v</span><span class="plain">, </span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="identifier">v</span><span class="plain"> - </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_O</span><span class="plain">) / (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::value_to_quanta appears nowhere else.</p>
<p class="endnote">The function Kinds::Scalings::real_value_to_quanta appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Scaled arithmetic at run-time. </b>We begin with routines to compile code which, at run-time, performs these
same operations: quanta to value, value to quanta and remainder. The
value is held in the I6 variable named <code class="display"><span class="extract">V_var</span></code>.
</p>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::compile_quanta_to_value</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">,</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">V_var</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">sgn_var</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">x_var</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">label</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="functiontext">Kinds::Scalings::compile_scale_and_add</span><span class="plain">(</span>
<span class="identifier">InterNames::to_symbol</span><span class="plain">(</span><span class="identifier">V_var</span><span class="plain">), </span><span class="identifier">sgn_var</span><span class="plain">, </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain">, </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_O</span><span class="plain">, </span><span class="identifier">x_var</span><span class="plain">, </span><span class="identifier">label</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">.0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">REAL_NUMBER_TY_TIMES_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::val_real</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_O</span><span class="plain"> != </span><span class="constant">0</span><span class="plain">.0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">REAL_NUMBER_TY_PLUS_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::val_real</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_O</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">REAL_NUMBER_TY_NAN_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">JUMP_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::lab</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">label</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::compile_quanta_to_value appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>The integer case of this is extracted as a utility routine because it's useful
for other calculations too. This performs the operation
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">v --&gt; kv + l</span>
</pre>
<p class="inwebparagraph">carefully checking that the result does not overflow the virtual machine's
signed integer size limit in the process. <code class="display"><span class="extract">k</span></code> is a constant known at compile
time, but <code class="display"><span class="extract">l</span></code> is an arbitrary I6 expression whose value can't be known until
run-time. If an overflow occurs, we jump to the given label.
</p>
<p class="inwebparagraph">If, at run-time, the variable <code class="display"><span class="extract">sgn</span></code> is negative, then we are performing this
on the absolute value of what will be a negative number; since we're using
twos-complement arithmetic, this increases the maxima by 1. Thus 32768 or
2147483648 will overflow in the positive domain, but not the negative.
</p>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::compile_scale_and_add</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">var</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">sgn_var</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">scale_factor</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">to_add</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">var_to_add</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">label</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">scale_factor</span><span class="plain"> &gt; </span><span class="constant">1</span><span class="plain">) {</span>
<span class="reserved">long</span><span class="plain"> </span><span class="reserved">long</span><span class="plain"> </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">max</span><span class="plain"> = </span><span class="constant">2147483647</span><span class="identifier">LL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TargetVMs::is_16_bit</span><span class="plain">(</span><span class="identifier">Task::vm</span><span class="plain">())) </span><span class="identifier">max</span><span class="plain"> = </span><span class="constant">32767</span><span class="identifier">LL</span><span class="plain">;</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">IFELSE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">sgn_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_object</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">Compile the overflow check</span> <span class="cwebmacronumber">18.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">max</span><span class="plain">++;</span>
&lt;<span class="cwebmacro">Compile the overflow check</span> <span class="cwebmacronumber">18.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">PLUS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">TIMES_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">scale_factor</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">var</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">PLUS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">to_add</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">var_to_add</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::compile_scale_and_add is used in <a href="#SP17">&#167;17</a>.</p>
<p class="inwebparagraph"><a id="SP18_1"></a><b>&#167;18.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile the overflow check</span> <span class="cwebmacronumber">18.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">OR_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">GT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) (</span><span class="identifier">max</span><span class="plain">/</span><span class="identifier">scale_factor</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">AND_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) (</span><span class="identifier">max</span><span class="plain">/</span><span class="identifier">scale_factor</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">GT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">PLUS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">to_add</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">var_to_add</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) (</span><span class="identifier">max</span><span class="plain">/</span><span class="identifier">scale_factor</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">JUMP_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::lab</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">label</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP18">&#167;18</a> (twice).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>And conversely... Note that in the real case, the remainder variable <code class="display"><span class="extract">R_var</span></code>
is ignored, since the division can be performed "exactly".
</p>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::compile_value_to_quanta</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">,</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">V_var</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">R_var</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_O</span><span class="plain"> != </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">MINUS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_O</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R_var</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">MODULO_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">DIVIDE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">int_M</span><span class="plain"> != </span><span class="constant">0</span><span class="plain">.0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">REAL_NUMBER_TY_MINUS_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::val_real</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_O</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">.0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">REAL_NUMBER_TY_DIVIDE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::val_real</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">sc</span><span class="plain">.</span><span class="element">real_M</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::compile_value_to_quanta is used in <a href="#SP21">&#167;21</a>.</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>The following compiles a valid condition to test whether the value in the
named I6 variable is equal to, greater than, less than or equal to, etc., the
quantum for the scaling. <code class="display"><span class="extract">op</span></code> contains the textual form of the comparison
operator to use: say, <code class="display"><span class="extract">"&gt;="</span></code>.
</p>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::compile_threshold_test</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">,</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">V_var</span><span class="plain">, </span><span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">op</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">op</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">NUMBER_TY_ABS_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="functiontext">Kinds::Scalings::quantum</span><span class="plain">(</span><span class="identifier">sc</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">REAL_NUMBER_TY_COMPARE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">REAL_NUMBER_TY_ABS_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_real</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Kinds::Scalings::real_quantum</span><span class="plain">(</span><span class="identifier">sc</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::compile_threshold_test appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b>We now compile code to print the value in the variable <code class="display"><span class="extract">V_var</span></code> with
respect to this scaling. We need two other variables at our disposal to
do this: <code class="display"><span class="extract">R_var</span></code>, which is temporary storage to hold the remainder part;
and <code class="display"><span class="extract">S_var</span></code>, which is a scratch variable used as a form of loop counter.
</p>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::compile_print_in_quanta</span><span class="plain">(</span><span class="reserved">scaling_transformation</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain">,</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">V_var</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">R_var</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">S_var</span><span class="plain">) {</span>
<span class="functiontext">Kinds::Scalings::compile_value_to_quanta</span><span class="plain">(</span><span class="identifier">sc</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sc</span><span class="plain">.</span><span class="element">use_integer_scaling</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINTNUMBER_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">GT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">Print a decimal expansion for the remainder</span> <span class="cwebmacronumber">21.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">REAL_NUMBER_TY_SAY_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">V_var</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::compile_print_in_quanta appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP21_1"></a><b>&#167;21.1. </b>In the integer case, then, suppose we have determined that our value is
2 quanta with remainder 26/Mths. We've already printed the 2, and it remains
to print the best decimal expansion we can to represent 26/Mths.
</p>
<p class="inwebparagraph">This splits into two cases. If <code class="display"><span class="extract">M</span></code> divides some power of 10 then the fraction
<code class="display"><span class="extract">26/M</span></code> can be written as a positive integer divided by a power of 10, and
that means the decimal expansion can be printed exactly: there are no
recurring decimals. If it can't, then we must approximate.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Print a decimal expansion for the remainder</span> <span class="cwebmacronumber">21.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_text</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">"."</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">M</span><span class="plain"> = </span><span class="identifier">sc</span><span class="plain">.</span><span class="identifier">int_M</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cl10M</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="reserved">while</span><span class="plain"> (</span><span class="identifier">M</span><span class="plain"> &gt; </span><span class="identifier">cl10M</span><span class="plain">) </span><span class="identifier">cl10M</span><span class="plain"> = </span><span class="identifier">cl10M</span><span class="plain">*10;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">"M = %d, ceiling(log_10(M)) = %d"</span><span class="plain">, </span><span class="identifier">M</span><span class="plain">, </span><span class="identifier">cl10M</span><span class="plain">);</span>
<span class="identifier">Emit::code_comment</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cl10M</span><span class="plain"> % </span><span class="identifier">M</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Use an exact method, since the multiplier divides a power of 10</span> <span class="cwebmacronumber">21.1.1</span>&gt;
<span class="reserved">else</span>
&lt;<span class="cwebmacro">Use an approximate method, since we can't have an exact one in all cases</span> <span class="cwebmacronumber">21.1.2</span>&gt;<span class="character">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP21">&#167;21</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1"></a><b>&#167;21.1.1. </b>In this exact case,
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">M = cl10M / t</span>
</pre>
<p class="inwebparagraph">for some natural number <code class="display"><span class="extract">t</span></code>, which means our example <code class="display"><span class="extract">26/M</span></code> is equal to
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">26t/Mt = 26t / cl10M</span>
.</pre>
<p class="inwebparagraph">Once we've done that, we simply work out how many initial 0s there should
be; print that many zeroes; and then print <code class="display"><span class="extract">26t</span></code> as if it's an integer.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Use an exact method, since the multiplier divides a power of 10</span> <span class="cwebmacronumber">21.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = </span><span class="identifier">cl10M</span><span class="plain">/</span><span class="identifier">M</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">TIMES_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">t</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">S_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">cl10M</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">WHILE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">AND_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">MODULO_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">10</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">GT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">DIVIDE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">10</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">S_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">DIVIDE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">S_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">10</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">WHILE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">LT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">DIVIDE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">S_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">10</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_text</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">"0"</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">S_var</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">DIVIDE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">S_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">10</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINTNUMBER_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP21_1">&#167;21.1</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_2"></a><b>&#167;21.1.2. </b>In this approximation, <code class="display"><span class="extract">R_var</span></code> is measured in units of <code class="display"><span class="extract">1/M</span></code>. Thus the first
digit after the decimal point should be <code class="display"><span class="extract">R_var</span></code> times <code class="display"><span class="extract">10/M</span></code>, the second
<code class="display"><span class="extract">R_var</span></code> times <code class="display"><span class="extract">100/M</span></code>, and so on.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Use an approximate method, since we can't have an exact one in all cases</span> <span class="cwebmacronumber">21.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">R</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">&lt;=</span><span class="identifier">M</span><span class="plain">) {</span>
<span class="identifier">R</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">*10;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">g</span><span class="plain"> = </span><span class="functiontext">Kinds::Dimensions::gcd</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">M</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINTNUMBER_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">MODULO_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">PLUS_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">MODULO_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">DIVIDE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">TIMES_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">R_var</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) (</span><span class="identifier">R</span><span class="plain">/</span><span class="identifier">g</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) (</span><span class="identifier">M</span><span class="plain">/</span><span class="identifier">g</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">10</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">10</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">10</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP21_1">&#167;21.1</a>.</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>And finally:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Scalings::I6_real_literal</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">double</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"$"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"+"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%g"</span><span class="plain">, </span><span class="identifier">x</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Scalings::I6_real_literal appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-fv.html">Back to 'Floating-Point Values'</a></li><li><i>(This section ends Chapter 2: Kinds.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>