1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/docs/kinds-module/2-sav.html
2020-05-03 01:20:55 +01:00

999 lines
187 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Scaled Arithmetic Values</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<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="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-src/Figures/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</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="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="../core-module/index.html">core</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="index.html"><span class="selectedlink">kinds</span></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="../problems-module/index.html">problems</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul><h2>Shared Modules</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Scaled Arithmetic Values' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 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></div>
<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="2-sav.html#SP1">&#167;1. Definitions</a></li><li><a href="2-sav.html#SP6">&#167;6. Logging</a></li><li><a href="2-sav.html#SP7">&#167;7. Definition</a></li><li><a href="2-sav.html#SP10">&#167;10. Enlarging and contracting</a></li><li><a href="2-sav.html#SP11">&#167;11. Using scalings</a></li><li><a href="2-sav.html#SP14">&#167;14. Scaled arithmetic at compile-time</a></li><li><a href="2-sav.html#SP17">&#167;17. Scaled arithmetic at run-time</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>Some literal patterns allow us to give values using scaled units. For
example, "1 g" and "1 kg" might both define constant values of the same
kind, but the "1" is read differently in the two cases: it's worth 1000
times as much in the second case.
</p>
<p class="commentary">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 <span class="extract"><span class="extract-syntax">x kg</span></span> is stored
as <span class="extract"><span class="extract-syntax">M*x + O</span></span> at run-time for constants <span class="extract"><span class="extract-syntax">M</span></span> and <span class="extract"><span class="extract-syntax">O</span></span>, the "multiplier"
and "offset". <span class="extract"><span class="extract-syntax">M</span></span> must be positive, <span class="extract"><span class="extract-syntax">O</span></span> must be positive or zero.
</p>
<p class="commentary">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="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. </b>We have to implement all of this twice, in subtly different ways, to
cope with the fact that some units use integer arithmetic and others
use real.
</p>
<ul class="items"><li>(a) Real units are easier. A value of <span class="extract"><span class="extract-syntax">1.0</span></span> stored at run-time equals
1 benchmark unit: in our length example, 1 m. Thus the <span class="extract"><span class="extract-syntax">M</span></span> value for the
benchmark scaling is always 1.0.
</li><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 <span class="extract"><span class="extract-syntax">M</span></span> value for the benchmark is now usually not 1 &mdash;
in this example, it's 1000, because one benchmark unit (1 m) is stored
as the integer 1000.
</li></ul>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b>The benchmark <span class="extract"><span class="extract-syntax">M</span></span> 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
<span class="extract"><span class="extract-syntax">M</span></span> 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="commentary">Since, as noted above, benchmark <span class="extract"><span class="extract-syntax">M</span></span> is always 1 for real values, there's
no need for rescaling with real arithmetic.
</p>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. </b>Scalings are defined one at a time, and usually in terms of each other.
We can't know the values of <span class="extract"><span class="extract-syntax">M</span></span> they end up with until all have been
defined.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">LP_SCALED_UP</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">LP_SCALED_DOWN</span><span class="plain-syntax"> -1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">LP_SCALED_AT</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">; </span><span class="comment-syntax"> or if not, use real</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">int_O</span><span class="plain-syntax">; </span><span class="comment-syntax"> the </span>\(O\)<span class="comment-syntax"> value described above, if integers used</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">int_M</span><span class="plain-syntax">; </span><span class="comment-syntax"> the </span>\(M\)<span class="comment-syntax"> value described above</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">real_O</span><span class="plain-syntax">; </span><span class="comment-syntax"> the </span>\(O\)<span class="comment-syntax"> value described above, if real numbers used</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">real_M</span><span class="plain-syntax">; </span><span class="comment-syntax"> the </span>\(M\)<span class="comment-syntax"> value described above</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> used only in the definition process</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">scaling_mode</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">LP_SCALED_*</span></span><span class="comment-syntax"> constants</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">int_scalar</span><span class="plain-syntax">; </span><span class="comment-syntax"> whichever of these is relevant according to the integer/real mode</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">real_scalar</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure scaling_transformation is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. Logging. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::describe</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"scaling: x units --&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%d x + %x stored at runtime (int)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">, </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%g x + %g stored at runtime (real)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax">, </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">scaling_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LP_SCALED_UP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" (defined as benchmark * "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LP_SCALED_DOWN:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" (defined as benchmark / "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LP_SCALED_AT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" (defined as scaled at "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%d)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_scalar</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%g)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_scalar</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. Definition. </b>A new scaling is given with a scale factor either pegging it absolutely, or
relative to the benchmark. At initial definition time, we don't calculate <span class="extract"><span class="extract-syntax">M</span></span>:
we just take notes for later.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::new</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">integer_valued</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">scaled</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">int_s</span><span class="plain-syntax">, </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">real_s</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">offset</span><span class="plain-syntax">, </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">real_offset</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">use_integer_scaling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">integer_valued</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">.0;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">integer_valued</span><span class="plain-syntax">) </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax"> = </span><span class="identifier-syntax">offset</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">double</span><span class="plain-syntax">) </span><span class="identifier-syntax">real_offset</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">.0;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">scaling_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">scaled</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_scalar</span><span class="plain-syntax"> = </span><span class="identifier-syntax">int_s</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_scalar</span><span class="plain-syntax"> = </span><span class="identifier-syntax">real_s</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. </b>Soon after definition, we may realise that real arithmetic is needed after
all, even though we previously expected it to use integers. So:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::convert_to_real</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_O</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">double</span><span class="plain-syntax">) </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_O</span><span class="plain-syntax">; </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_O</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_M</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">double</span><span class="plain-syntax">) </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_M</span><span class="plain-syntax">; </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_M</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_scalar</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">double</span><span class="plain-syntax">) </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_scalar</span><span class="plain-syntax">; </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_scalar</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_integer_scaling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b>Each new scaling in turn is added to the list of those in use for a given
kind. For example, when the "1 km" scaling is added to those for lengths,
perhaps "1 cm" and "1 m" (the benchmark) already exist, but "1 mm" doesn't.
We call the following routine to calculate a suitable <span class="extract"><span class="extract-syntax">M</span></span> for the scaling.
It returns a value which is either <span class="extract"><span class="extract-syntax">-1</span></span>, or else a scale factor by which
to increase the <span class="extract"><span class="extract-syntax">M</span></span> values of everything else in the list.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::determine_M</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sc</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">benchmark_sc</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">first</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">equiv</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">alt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rescale_the_others_by_this</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="comment-syntax"> in effect, don't</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-sav.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Determine M for the first scaling of the list</span><span class="named-paragraph-number">9.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-sav.html#SP9_2" class="named-paragraph-link"><span class="named-paragraph">Determine M for a subsequent scaling of the list</span><span class="named-paragraph-number">9.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rescale_the_others_by_this</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9_1"></a><b>&#167;9.1. </b>This is the easy case &mdash; there's no list yet, and no benchmark yet. The <span class="extract"><span class="extract-syntax">M</span></span>
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="commentary">in which case, of course, <span class="extract"><span class="extract-syntax">M</span></span> 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 <span class="extract"><span class="extract-syntax">equiv</span></span> flag is set.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Determine M for the first scaling of the list</span><span class="named-paragraph-number">9.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_scalar</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_scalar</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">.0)) &amp;&amp;</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling_mode</span><span class="plain-syntax"> == </span><span class="constant-syntax">LP_SCALED_UP</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling_mode</span><span class="plain-syntax"> == </span><span class="constant-syntax">LP_SCALED_DOWN</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">equiv</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling_mode</span><span class="plain-syntax"> == </span><span class="constant-syntax">LP_SCALED_AT</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_integer_scaling</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))))</span>
<span class="plain-syntax"> </span><a href="2-knd.html#SP38" class="function-link"><span class="function-syntax">Kinds::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">LPCantScaleYet_KINDERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_scalar</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-sav.html#SP9">&#167;9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2"></a><b>&#167;9.2. </b>The harder case, when some scalings already exist for this kind. Firstly,
you can't create an alternative set of scalings (e.g. Imperial units such
as feet and inches) with its own absolute scale factor, because the existing
scalings (metric units such as mm, km, etc.) already have their <span class="extract"><span class="extract-syntax">M</span></span> value.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Determine M for a subsequent scaling of the list</span><span class="named-paragraph-number">9.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_scalar</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_scalar</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">.0)) &amp;&amp;</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">alt</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling_mode</span><span class="plain-syntax"> == </span><span class="constant-syntax">LP_SCALED_AT</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><a href="2-knd.html#SP38" class="function-link"><span class="function-syntax">Kinds::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">LPCantScaleTwice_KINDERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">equiv</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-sav.html#SP9_2_1" class="named-paragraph-link"><span class="named-paragraph">Calculate the multiplier for this equivalent scaling</span><span class="named-paragraph-number">9.2.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-sav.html#SP9_2_2" class="named-paragraph-link"><span class="named-paragraph">Calculate the multiplier for the LP relative to the benchmark</span><span class="named-paragraph-number">9.2.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-sav.html#SP9">&#167;9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_1"></a><b>&#167;9.2.1. </b>An equivalent unit exactly specifies its <span class="extract"><span class="extract-syntax">M</span></span>-value. For example:
</p>
<blockquote>
<p>1 pencil specifies a length equivalent to 18cm.</p>
</blockquote>
<p class="commentary">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 <span class="extract"><span class="extract-syntax">M</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate the multiplier for this equivalent scaling</span><span class="named-paragraph-number">9.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_integer_scaling</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_scalar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_scalar</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-sav.html#SP9_2">&#167;9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_2"></a><b>&#167;9.2.2. </b>Finally the trickiest case. We calculate <span class="extract"><span class="extract-syntax">M</span></span> based on scaling the benchmark
either up or down.
</p>
<p class="commentary">Scaling up by <span class="extract"><span class="extract-syntax">k</span></span> is no problem: the <span class="extract"><span class="extract-syntax">M</span></span> value is just <span class="extract"><span class="extract-syntax">k</span></span> times the benchmark
<span class="extract"><span class="extract-syntax">M</span></span>, which we call <span class="extract"><span class="extract-syntax">B</span></span>.
</p>
<p class="commentary">Scaling down might look similar: we want <span class="extract"><span class="extract-syntax">M = B/k</span></span>. But in integer arithmetic
<span class="extract"><span class="extract-syntax">k</span></span> probably doesn't divide <span class="extract"><span class="extract-syntax">B</span></span>, and extreme cases frequently occur: for
example, where <span class="extract"><span class="extract-syntax">k</span></span> is 1000 and <span class="extract"><span class="extract-syntax">B</span></span> is 1.
</p>
<p class="commentary">We get around this by increasing every <span class="extract"><span class="extract-syntax">M</span></span>-value in the list by a factor of:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> k / gcd(B, k)</span>
</pre>
<p class="commentary">Note that <span class="extract"><span class="extract-syntax">B</span></span> also increases in this process, and in fact becomes
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> Bk / gcd(B, k)</span>
</pre>
<p class="commentary">which is the smallest multiple of <span class="extract"><span class="extract-syntax">B</span></span> which has <span class="extract"><span class="extract-syntax">k</span></span> as a factor. (If in fact
<span class="extract"><span class="extract-syntax">k</span></span> always divided <span class="extract"><span class="extract-syntax">B</span></span>, then the scale multiple is 1 and no change is made.)
That means that the new value of <span class="extract"><span class="extract-syntax">B</span></span> divided by <span class="extract"><span class="extract-syntax">k</span></span> will be
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> B / gcd(B, k)</span>
</pre>
<p class="commentary">so this is what we set <span class="extract"><span class="extract-syntax">M</span></span> to.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate the multiplier for the LP relative to the benchmark</span><span class="named-paragraph-number">9.2.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">benchmark_sc</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no benchmark for comparison"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling_mode</span><span class="plain-syntax"> == </span><span class="constant-syntax">LP_SCALED_DOWN</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">benchmark_sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_M</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_scalar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">g</span><span class="plain-syntax"> = </span><a href="2-dmn.html#SP20" class="function-link"><span class="function-syntax">Kinds::Dimensions::gcd</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">B</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">/</span><span class="identifier-syntax">g</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rescale_the_others_by_this</span><span class="plain-syntax"> = </span><span class="identifier-syntax">k</span><span class="plain-syntax">/</span><span class="identifier-syntax">g</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">benchmark_sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_M</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_scalar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">/</span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling_mode</span><span class="plain-syntax"> == </span><span class="constant-syntax">LP_SCALED_UP</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">benchmark_sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_M</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_scalar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">int_M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">*</span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">benchmark_sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_M</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_scalar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">real_M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">*</span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-sav.html#SP9_2">&#167;9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. Enlarging and contracting. </b>Note that the offset values <span class="extract"><span class="extract-syntax">O</span></span> 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="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::enlarge</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">int_M</span><span class="plain-syntax"> *= </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">real_M</span><span class="plain-syntax"> *= </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::contract</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loses_accuracy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">loses_accuracy</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax"> % </span><span class="identifier-syntax">F</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) *</span><span class="identifier-syntax">loses_accuracy</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">int_M</span><span class="plain-syntax"> /= </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">real_M</span><span class="plain-syntax"> /= </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. Using scalings. </b>First, here's a <span class="extract"><span class="extract-syntax">strcmp</span></span>-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="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::compare</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax"> != </span><span class="identifier-syntax">B</span><span class="plain-syntax">.</span><span class="element-syntax">use_integer_scaling</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"scalings incomparable"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">B</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">B</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">B</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">B</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">B</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">B</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">B</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">B</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>Second, the following returns <span class="extract"><span class="extract-syntax">M</span></span> unless we're in real mode, in which case it
returns 1.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::get_integer_multiplier</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13"></a><b>&#167;13. </b>Finally, this simply detects the presence of a scale factor, real or integer:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::involves_scale_change</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">int_M</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">real_M</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">.0) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14"></a><b>&#167;14. Scaled arithmetic at compile-time. </b>The "quantum" of a scaling is the run-time value corresponding to 1 unit:
for example, for kilometers, it's the run-time value which "1 km" translates
into.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::quantum</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Kinds::Scalings::quantum</span></span>:<br/><a href="2-sav.html#SP20">&#167;20</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><a href="2-sav.html#SP15" class="function-link"><span class="function-syntax">Kinds::Scalings::quanta_to_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sc</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::real_quantum</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Kinds::Scalings::real_quantum</span></span>:<br/><a href="2-sav.html#SP20">&#167;20</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-sav.html#SP15" class="function-link"><span class="function-syntax">Kinds::Scalings::real_quanta_to_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sc</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">.0);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15"></a><b>&#167;15. </b>More generally, the following takes a number of quanta and turns it into
the run-time value that stores as:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::quanta_to_value</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Kinds::Scalings::quanta_to_value</span></span>:<br/><a href="2-sav.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">q</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">q</span><span class="plain-syntax">*</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax"> + </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::real_quanta_to_value</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Kinds::Scalings::real_quanta_to_value</span></span>:<br/><a href="2-sav.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">, </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">q</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">q</span><span class="plain-syntax">*</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax"> + </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16"></a><b>&#167;16. </b>In integer arithmetic, the inverse of this function won't generally
exist, since division can't be performed exactly. The following is the
best we can do.
</p>
<p class="commentary">So consider the run-time value <span class="extract"><span class="extract-syntax">v</span></span>, 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
<span class="extract"><span class="extract-syntax">v = 2643</span></span> produces 2 quanta and remainder 643/1000ths.
</p>
<p class="commentary">In real arithmetic, on the other hand, the inverse straightforwardly exists.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::value_to_quanta</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">q</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">r</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"inversion unimplemented"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">r</span><span class="plain-syntax">) *</span><span class="identifier-syntax">r</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">v</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax">) % (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">q</span><span class="plain-syntax">) *</span><span class="identifier-syntax">q</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">v</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax">) / (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::real_value_to_quanta</span><span class="plain-syntax">(</span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">v</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax">) / (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">real_M</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17"></a><b>&#167;17. Scaled arithmetic at run-time. </b>We begin with routines to compile code which, at run-time, performs these
same operations: quanta to value, value to quanta and remainder. The
value is held in the I6 variable named <span class="extract"><span class="extract-syntax">V_var</span></span>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::compile_quanta_to_value</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sgn_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">x_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">label</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-sav.html#SP18" class="function-link"><span class="function-syntax">Kinds::Scalings::compile_scale_and_add</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">InterNames::to_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">V_var</span><span class="plain-syntax">), </span><span class="identifier-syntax">sgn_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">, </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax">, </span><span class="identifier-syntax">x_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">label</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">.0) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_TIMES_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">.0) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_PLUS_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_NAN_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">JUMP_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::lab</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">label</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18"></a><b>&#167;18. </b>The integer case of this is extracted as a utility routine because it's useful
for other calculations too. This performs the operation
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> v --&gt; kv + l</span>
</pre>
<p class="commentary">carefully checking that the result does not overflow the virtual machine's
signed integer size limit in the process. <span class="extract"><span class="extract-syntax">k</span></span> is a constant known at compile
time, but <span class="extract"><span class="extract-syntax">l</span></span> 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="commentary">If, at run-time, the variable <span class="extract"><span class="extract-syntax">sgn</span></span> 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="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::compile_scale_and_add</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Kinds::Scalings::compile_scale_and_add</span></span>:<br/><a href="2-sav.html#SP17">&#167;17</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sgn_var</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">to_add</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var_to_add</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">label</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max</span><span class="plain-syntax"> = </span><span class="constant-syntax">2147483647</span><span class="identifier-syntax">LL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TargetVMs::is_16_bit</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::vm</span><span class="plain-syntax">())) </span><span class="identifier-syntax">max</span><span class="plain-syntax"> = </span><span class="constant-syntax">32767</span><span class="identifier-syntax">LL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">IFELSE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">sgn_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-sav.html#SP18_1" class="named-paragraph-link"><span class="named-paragraph">Compile the overflow check</span><span class="named-paragraph-number">18.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">max</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-sav.html#SP18_1" class="named-paragraph-link"><span class="named-paragraph">Compile the overflow check</span><span class="named-paragraph-number">18.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">TIMES_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">to_add</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_to_add</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18_1"></a><b>&#167;18.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the overflow check</span><span class="named-paragraph-number">18.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">OR_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) (</span><span class="identifier-syntax">max</span><span class="plain-syntax">/</span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) (</span><span class="identifier-syntax">max</span><span class="plain-syntax">/</span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">to_add</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">var_to_add</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) (</span><span class="identifier-syntax">max</span><span class="plain-syntax">/</span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">JUMP_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::lab</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">label</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-sav.html#SP18">&#167;18</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP19"></a><b>&#167;19. </b>And conversely... Note that in the real case, the remainder variable <span class="extract"><span class="extract-syntax">R_var</span></span>
is ignored, since the division can be performed "exactly".
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::compile_value_to_quanta</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Kinds::Scalings::compile_value_to_quanta</span></span>:<br/><a href="2-sav.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R_var</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">MINUS_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_O</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R_var</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">MODULO_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">.0) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_MINUS_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_O</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">.0) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_DIVIDE_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">real_M</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20"></a><b>&#167;20. </b>The following compiles a valid condition to test whether the value in the
named I6 variable is equal to, greater than, less than or equal to, etc., the
quantum for the scaling. <span class="extract"><span class="extract-syntax">op</span></span> contains the textual form of the comparison
operator to use: say, <span class="extract"><span class="extract-syntax">"&gt;="</span></span>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::compile_threshold_test</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">op</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">op</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">NUMBER_TY_ABS_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) </span><a href="2-sav.html#SP14" class="function-link"><span class="function-syntax">Kinds::Scalings::quantum</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sc</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_COMPARE_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_ABS_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><a href="2-sav.html#SP14" class="function-link"><span class="function-syntax">Kinds::Scalings::real_quantum</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sc</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21"></a><b>&#167;21. </b>We now compile code to print the value in the variable <span class="extract"><span class="extract-syntax">V_var</span></span> with
respect to this scaling. We need two other variables at our disposal to
do this: <span class="extract"><span class="extract-syntax">R_var</span></span>, which is temporary storage to hold the remainder part;
and <span class="extract"><span class="extract-syntax">S_var</span></span>, which is a scratch variable used as a form of loop counter.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::compile_print_in_quanta</span><span class="plain-syntax">(</span><span class="reserved-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S_var</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-sav.html#SP19" class="function-link"><span class="function-syntax">Kinds::Scalings::compile_value_to_quanta</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sc</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="identifier-syntax">use_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">PRINTNUMBER_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-sav.html#SP21_1" class="named-paragraph-link"><span class="named-paragraph">Print a decimal expansion for the remainder</span><span class="named-paragraph-number">21.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">REAL_NUMBER_TY_SAY_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">V_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21_1"></a><b>&#167;21.1. </b>In the integer case, then, suppose we have determined that our value is
2 quanta with remainder 26/Mths. We've already printed the 2, and it remains
to print the best decimal expansion we can to represent 26/Mths.
</p>
<p class="commentary">This splits into two cases. If <span class="extract"><span class="extract-syntax">M</span></span> divides some power of 10 then the fraction
<span class="extract"><span class="extract-syntax">26/M</span></span> 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="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Print a decimal expansion for the remainder</span><span class="named-paragraph-number">21.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">PRINT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">I</span><span class="string-syntax">"."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sc</span><span class="plain-syntax">.</span><span class="element-syntax">int_M</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cl10M</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">M</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">cl10M</span><span class="plain-syntax">) </span><span class="identifier-syntax">cl10M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cl10M</span><span class="plain-syntax">*10;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="string-syntax">"M = %d, ceiling(log_10(M)) = %d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">M</span><span class="plain-syntax">, </span><span class="identifier-syntax">cl10M</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Emit::code_comment</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cl10M</span><span class="plain-syntax"> % </span><span class="identifier-syntax">M</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-sav.html#SP21_1_1" class="named-paragraph-link"><span class="named-paragraph">Use an exact method, since the multiplier divides a power of 10</span><span class="named-paragraph-number">21.1.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-sav.html#SP21_1_2" class="named-paragraph-link"><span class="named-paragraph">Use an approximate method, since we can't have an exact one in all cases</span><span class="named-paragraph-number">21.1.2</span></a></span><span class="character-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-sav.html#SP21">&#167;21</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP21_1_1"></a><b>&#167;21.1.1. </b>In this exact case,
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> M = cl10M / t</span>
</pre>
<p class="commentary">for some natural number <span class="extract"><span class="extract-syntax">t</span></span>, which means our example <span class="extract"><span class="extract-syntax">26/M</span></span> is equal to
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> 26t/Mt = 26t / cl10M</span>
</pre>
<p class="commentary">Once we've done that, we simply work out how many initial 0s there should
be; print that many zeroes; and then print <span class="extract"><span class="extract-syntax">26t</span></span> as if it's an integer.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Use an exact method, since the multiplier divides a power of 10</span><span class="named-paragraph-number">21.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cl10M</span><span class="plain-syntax">/</span><span class="identifier-syntax">M</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">t</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">TIMES_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">S_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">cl10M</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">WHILE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">MODULO_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">GT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">S_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">S_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">WHILE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">LT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">S_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">PRINT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">I</span><span class="string-syntax">"0"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">S_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">S_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">PRINTNUMBER_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-sav.html#SP21_1">&#167;21.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP21_1_2"></a><b>&#167;21.1.2. </b>In this approximation, <span class="extract"><span class="extract-syntax">R_var</span></span> is measured in units of <span class="extract"><span class="extract-syntax">1/M</span></span>. Thus the first
digit after the decimal point should be <span class="extract"><span class="extract-syntax">R_var</span></span> times <span class="extract"><span class="extract-syntax">10/M</span></span>, the second
<span class="extract"><span class="extract-syntax">R_var</span></span> times <span class="extract"><span class="extract-syntax">100/M</span></span>, and so on.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Use an approximate method, since we can't have an exact one in all cases</span><span class="named-paragraph-number">21.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">M</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">*10;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">g</span><span class="plain-syntax"> = </span><a href="2-dmn.html#SP20" class="function-link"><span class="function-syntax">Kinds::Dimensions::gcd</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">M</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">PRINTNUMBER_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">MODULO_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">MODULO_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">TIMES_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) (</span><span class="identifier-syntax">R</span><span class="plain-syntax">/</span><span class="identifier-syntax">g</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_t</span><span class="plain-syntax">) (</span><span class="identifier-syntax">M</span><span class="plain-syntax">/</span><span class="identifier-syntax">g</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-sav.html#SP21_1">&#167;21.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22"></a><b>&#167;22. </b>And finally:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Scalings::I6_real_literal</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"$"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">x</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"+"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%g"</span><span class="plain-syntax">, </span><span class="identifier-syntax">x</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="2-fv.html">&#10094;</a></li><li class="progresschapter"><a href="1-km.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-itk.html">itk</a></li><li class="progresssection"><a href="2-knd.html">knd</a></li><li class="progresssection"><a href="2-kc.html">kc</a></li><li class="progresssection"><a href="2-kc2.html">kc2</a></li><li class="progresssection"><a href="2-ki.html">ki</a></li><li class="progresssection"><a href="2-uk.html">uk</a></li><li class="progresssection"><a href="2-dk.html">dk</a></li><li class="progresssection"><a href="2-dmn.html">dmn</a></li><li class="progresssection"><a href="2-fv.html">fv</a></li><li class="progresscurrent">sav</li><li class="progressnextoff">&#10095;</li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>