mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 08:34:22 +03:00
1155 lines
147 KiB
HTML
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">§1. Definitions</a></li><li><a href="#SP6">§6. Logging</a></li><li><a href="#SP7">§7. Definition</a></li><li><a href="#SP10">§10. Enlarging and contracting</a></li><li><a href="#SP11">§11. Using scalings</a></li><li><a href="#SP14">§14. Scaled arithmetic at compile-time</a></li><li><a href="#SP17">§17. Scaled arithmetic at run-time</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Definitions. </b></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§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>§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 —
|
|
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>§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>§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>§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 --> "</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>§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>§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">-></span><span class="element">use_integer_scaling</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">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="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_M</span><span class="plain"> = (</span><span class="reserved">double</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_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_scalar</span><span class="plain"> = (</span><span class="reserved">double</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">sc</span><span class="plain">-></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">-></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>§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><<span class="cwebmacro">Determine M for the first scaling of the list</span> <span class="cwebmacronumber">9.1</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><<span class="cwebmacro">Determine M for a subsequent scaling of the list</span> <span class="cwebmacronumber">9.2</span>><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>§9.1. </b>This is the easy case — 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">
|
|
<<span class="cwebmacrodefn">Determine M for the first scaling of the list</span> <span class="cwebmacronumber">9.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">sc</span><span class="plain">-></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">-></span><span class="element">real_scalar</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">.0)) &&</span>
|
|
<span class="plain">((</span><span class="identifier">sc</span><span class="plain">-></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">-></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">-></span><span class="element">scaling_mode</span><span class="plain"> == </span><span class="constant">LP_SCALED_AT</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="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">-></span><span class="element">int_M</span><span class="plain"> = </span><span class="identifier">sc</span><span class="plain">-></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">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_2"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Determine M for a subsequent scaling of the list</span> <span class="cwebmacronumber">9.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">sc</span><span class="plain">-></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">-></span><span class="element">real_scalar</span><span class="plain"> != </span><span class="constant">1</span><span class="plain">.0)) &&</span>
|
|
<span class="plain">((</span><span class="identifier">alt</span><span class="plain">) && (</span><span class="identifier">sc</span><span class="plain">-></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>
|
|
<<span class="cwebmacro">Calculate the multiplier for this equivalent scaling</span> <span class="cwebmacronumber">9.2.1</span>>
|
|
<span class="reserved">else</span>
|
|
<<span class="cwebmacro">Calculate the multiplier for the LP relative to the benchmark</span> <span class="cwebmacronumber">9.2.2</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_2_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Calculate the multiplier for this equivalent scaling</span> <span class="cwebmacronumber">9.2.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<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">sc</span><span class="plain">-></span><span class="element">int_scalar</span><span class="plain">;</span>
|
|
<span class="reserved">else</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_scalar</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9_2">§9.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_2_2"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Calculate the multiplier for the LP relative to the benchmark</span> <span class="cwebmacronumber">9.2.2</span>> =
|
|
</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">-></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">-></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">-></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">-></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">-></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">-></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">-></span><span class="element">real_scalar</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">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">-></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">-></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">-></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">-></span><span class="element">int_scalar</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">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">-></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">-></span><span class="element">real_scalar</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">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">§9.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§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>§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"> > </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"> < </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"> > </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"> < </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"> > </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"> < </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"> > </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"> < </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>§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>§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>§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">§20</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Scalings::real_quantum is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§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">§14</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Scalings::real_quanta_to_value is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§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>§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>§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 --> 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"> > </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>
|
|
<<span class="cwebmacro">Compile the overflow check</span> <span class="cwebmacronumber">18.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>
|
|
<span class="identifier">max</span><span class="plain">++;</span>
|
|
<<span class="cwebmacro">Compile the overflow check</span> <span class="cwebmacronumber">18.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::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">§17</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18_1"></a><b>§18.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Compile the overflow check</span> <span class="cwebmacronumber">18.1</span>> =
|
|
</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">§18</a> (twice).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§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">§21</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§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">">="</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>§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>
|
|
<<span class="cwebmacro">Print a decimal expansion for the remainder</span> <span class="cwebmacronumber">21.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::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>§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">
|
|
<<span class="cwebmacrodefn">Print a decimal expansion for the remainder</span> <span class="cwebmacronumber">21.1</span>> =
|
|
</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"> > </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>
|
|
<<span class="cwebmacro">Use an exact method, since the multiplier divides a power of 10</span> <span class="cwebmacronumber">21.1.1</span>>
|
|
<span class="reserved">else</span>
|
|
<<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>><span class="character">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP21">§21</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21_1_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Use an exact method, since the multiplier divides a power of 10</span> <span class="cwebmacronumber">21.1.1</span>> =
|
|
</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">§21.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21_1_2"></a><b>§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">
|
|
<<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>> =
|
|
</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"><=</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">§21.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§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"> > </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>
|
|
|