mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
1681 lines
295 KiB
HTML
1681 lines
295 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Dimensions</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-assets/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="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="../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>Services</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="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Dimensions' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Services</a></li><li><a href="index.html">kinds</a></li><li><a href="index.html#3">Chapter 3: Arithmetic</a></li><li><b>Dimensions</b></li></ul></div>
|
|
<p class="purpose">To keep a small database indicating the physical dimensions of numerical values, and how they combine: for instance, allowing us to specify that a length times a length is an area.</p>
|
|
|
|
<ul class="toc"><li><a href="3-dmn.html#SP13">§13. Prior kinds</a></li><li><a href="3-dmn.html#SP14">§14. Multiplication lists</a></li><li><a href="3-dmn.html#SP18">§18. Unary operations</a></li><li><a href="3-dmn.html#SP19">§19. Euclid's algorithm</a></li><li><a href="3-dmn.html#SP21">§21. Unit sequences</a></li><li><a href="3-dmn.html#SP29">§29. Performing derivations</a></li><li><a href="3-dmn.html#SP30">§30. Classifying the units</a></li><li><a href="3-dmn.html#SP33">§33. Scaling</a></li><li><a href="3-dmn.html#SP39">§39. Arithmetic on kinds</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1"></a><b>§1. </b>Dimension in this sense is a term drawn from physics. The idea is that when
|
|
quantities are multiplied together, their natures are combined as well as
|
|
the actual numbers involved. For instance, in
|
|
$$ v = f\lambda $$
|
|
if the frequency \(f\) of a wave is measured in Hz (counts per second), and
|
|
the wavelength \(\lambda\) in m, then the velocity \(v\) must be measured
|
|
in m/s: and that is indeed a measure of velocity, so this looks right.
|
|
We can tell that the formula
|
|
$$ v = f^2\lambda $$
|
|
must be wrong because it would result in an acceleration. Physicists use the
|
|
term "dimensions" much as Inform uses the term "kinds of value".
|
|
</p>
|
|
|
|
<p class="commentary">Inform applies dimension-checking to all "quasinumerical" kinds — those
|
|
which can be expressed numerically. The choice of which kinds are quasinumerical
|
|
is all done in the I6 template, not built into Inform at the compiler level,
|
|
but the standard setup makes number, time, intermediate results of calculations
|
|
(see below), and what the Inform documentation calls "units" — kinds of
|
|
value specified by literal patterns.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP2"></a><b>§2. </b>Inform divides quasinumerical kinds into three: fundamental units, derived units
|
|
with dimensions, and dimensionless units. In the default setup provided by
|
|
the template, a typical run has one fundamental unit ("time"), one
|
|
dimensionless unit ("number") and — unless the source text does
|
|
something very strange — no derived units.
|
|
</p>
|
|
|
|
<p class="commentary">It would no doubt be cool to distinguish these by applying Buckingham's
|
|
\(\pi\)-theorem to all the equations we need to use, but this is a tricky
|
|
technique and does not always produce the "natural" results which people
|
|
expect. Instead, Inform requires the writer to specify explicitly how units
|
|
combine.
|
|
</p>
|
|
|
|
<p class="commentary">Number and time are built-in special cases. Further fundamental units are created
|
|
every time source text like this is read:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Mass is a kind of value. 1kg specifies a mass.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">Derived units only come about when the source text specifies a multiplication
|
|
rule. For instance, when Inform reads
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>A mass times an acceleration specifies a force.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">it chooses one of the three units — say, force — and derives that from the
|
|
others.
|
|
</p>
|
|
|
|
<p class="commentary">Multiplication rules are stored in a linked list associated with left operand;
|
|
so that the rule \(A\) times \(B\) specifies \(C\) causes \((B, C)\) to be stored
|
|
in the list of <span class="extract"><span class="extract-syntax">multiplications</span></span> belonging to \(A\).
|
|
</p>
|
|
|
|
<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">dimensional_rules</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">multiplications</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">dimensional_rules</span><span class="plain-syntax">;</span>
|
|
|
|
<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">dimensional_rule</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">name</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">right</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure dimensional_rules is private to this section.</li><li>The structure dimensional_rule is accessed in 2/kc and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3"></a><b>§3. </b>The derivation process can be seen in action by feeding Inform
|
|
definitions of the SI units (see the test case <span class="extract"><span class="extract-syntax">SIUnits-G</span></span>) and looking at
|
|
the output of:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Test dimensions (internal) with --.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">(The dash is meaningless — this is a test with no input.) In the output, we
|
|
see that
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> Base units: time, length, mass, elapsed time, electric current, temperature, luminosity</span>
|
|
<span class="plain-syntax"> Derived units:</span>
|
|
<span class="plain-syntax"> frequency = (elapsed time)-1</span>
|
|
<span class="plain-syntax"> force = (length).(mass).(elapsed time)-2</span>
|
|
<span class="plain-syntax"> energy = (length)2.(mass).(elapsed time)-2</span>
|
|
<span class="plain-syntax"> pressure = (length)-1.(mass).(elapsed time)-2</span>
|
|
<span class="plain-syntax"> power = (length)2.(mass).(elapsed time)-3</span>
|
|
<span class="plain-syntax"> electric charge = (elapsed time).(electric current)</span>
|
|
<span class="plain-syntax"> voltage = (length)2.(mass).(elapsed time)-3.(electric current)-1</span>
|
|
</pre>
|
|
<p class="commentary">...and so on. Those expressions on the right hand sides are "derived units",
|
|
where the numbers are powers, so that negative numbers mean division.
|
|
It's easy to see why we want to give names and notations for some of
|
|
these derived units — imagine going into a cycle shop and asking for a
|
|
\(5 {\rm m}^2\cdot{\rm kg}\cdot{\rm s}^{-3}\cdot{\rm A}^{-1}\) battery.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP4"></a><b>§4. </b>A "dimensionless" quantity is one which is just a number, and is not a
|
|
physical measurement as such. In an equation like
|
|
$$ K = {{mv^2}\over{2}} $$
|
|
the 2 is clearly dimensionless, but other possibilities also exist. The
|
|
arc length of part of a circle at radius \(r\) drawn out to angle \(\theta\)
|
|
(if measured in radians) is given by:
|
|
$$ A = \theta r $$
|
|
Here \(A\) and \(r\) are both lengths, so the angle \(\theta\) must be dimensionless.
|
|
But clearly it's not quite conceptually the same thing as an ordinary number.
|
|
Inform creates new dimensionless quantities this way, too:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Angle is a kind of value. 1 rad specifies an angle. Length times angle specifies a length.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">Inform is not quite so careful about distinguishing dimensionless quantities
|
|
as some physicists might be. The official SI units distinguish angle, measured
|
|
in radians, and solid angle, in steradians, writing them as having units
|
|
\({\rm m}\cdot{\rm m}^{-1}\) and \({\rm m}^2\cdot{\rm m}^{-2}\) respectively —
|
|
one is a ratio of lengths, the other of areas. Inform cancels the units
|
|
and sees them as dimensionally equal. So if we write:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Solid angle is a kind of value. 1 srad specifies an solid angle. Area times solid angle specifies an area.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">then Inform treats angle and solid angle as having the same multiplicative
|
|
properties — but it still allows variables to have either one as a kind of
|
|
value, and prints them differently.
|
|
</p>
|
|
|
|
<p class="commentary">Note that a dimensionless unit (other than number) can only get that way
|
|
by derivation, so it is always a derived unit, never a fundamental unit.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP5"></a><b>§5. </b>In the process of calculations, we often need to create other and nameless
|
|
units as partial answers of calculations. Consider the kinetic energy equation
|
|
$$ K = {{mv^2}\over{2}} $$
|
|
being evaluated the way a computer does it, one step at a time. One way takes
|
|
the mass, multiplies by the velocity to get a momentum, multiplies by the
|
|
velocity again to get energy, then divides by a dimensionless constant. But
|
|
another way would be to square the velocity first, then multiply by mass
|
|
to get energy, then halve. If we do it that way, what units are the squared
|
|
velocity in? The answer has to be
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> (length)2.(elapsed time)-2</span>
|
|
</pre>
|
|
<p class="commentary">but that's a unit which isn't useful for much, and doesn't have any everyday
|
|
name. Inform creates what are called "intermediate kinds" like this in
|
|
order to be able to represent the kinds of intermediate values which turn
|
|
up in calculation. They use the special <span class="extract"><span class="extract-syntax">CON_INTERMEDIATE</span></span> construction, they
|
|
are nameless, and the user isn't allowed to store the results permanently.
|
|
(They can't be the kind of a global variable, a table column, and so on.)
|
|
If the user wants to deal with such values on a long-term basis, he must give
|
|
them a name, like this:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Funkiness is a kind of value. 1 Claude is a funkiness. A velocity times a velocity specifies a funkiness.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP6"></a><b>§6. </b>Expressions like \({\rm m}^2\cdot{\rm kg}\) are stored inside Inform as
|
|
sequences of ordered pairs in the form
|
|
$$ ((B_1, p_1), (B_2, p_2), ..., (B_k, p_k)) $$
|
|
where each \(B_i\) is the type ID of a fundamental unit, each \(p_i\) is a non-zero
|
|
integer, and \(B_1 < B_2 < ... < B_k\). For instance, energy would be
|
|
$$ (({\rm length}, 2), ({\rm mass}, 1), ({\rm elapsed~time}, -2)). $$
|
|
</p>
|
|
|
|
<p class="commentary">Every physically different derived unit has a unique and distinct sequence.
|
|
This is only true because a unit sequence is forbidden to contain derived
|
|
units. For instance, specific heat capacity looks as if it is written with
|
|
two different units in physics:
|
|
\(\) {\rm J}\cdot {\rm K}^{-1}\cdot {\rm kg}^{-1} \quad = \quad
|
|
{\rm m}^2\cdot{\rm s}^{-2}\cdot{\rm K}^{-1} \(\)
|
|
But this is because the Joule is a derived unit. Substituting
|
|
\({\rm J} = {\rm m}^2\cdot{\rm kg}\cdot{\rm s}^{-2}\)
|
|
to get back to fundamental units shows that both sides would be computed as the
|
|
same unit sequence.
|
|
</p>
|
|
|
|
<p class="commentary">The case \(k=0\), the empty sequence, is not only legal but important: it is
|
|
the derivation for a dimensionless unit. (As discussed above, Inform doesn't
|
|
see different dimensionless units as being physically different.)
|
|
</p>
|
|
|
|
<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">unit_pair</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fund_unit</span><span class="plain-syntax">; </span><span class="comment-syntax"> and this really must be a fundamental kind</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">power</span><span class="plain-syntax">; </span><span class="comment-syntax"> a non-zero integer</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">unit_pair</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure unit_pair is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP7"></a><b>§7. </b>The following is a hard limit, but really not a problematic one. The
|
|
entire SI system has only 7 fundamental units, and the only named scientific
|
|
unit I've seen which has even 5 terms in its derivation is molar entropy, a
|
|
less than everyday chemical measure
|
|
(\({\rm kg}\cdot{\rm m}^2\cdot{\rm s}^{-2}\cdot{\rm K}^{-1}\cdot{\rm mol}^{-1}\),
|
|
if you're taking notes).
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span><span class="plain-syntax"> </span><span class="constant-syntax">16</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">unit_sequence</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">no_unit_pairs</span><span class="plain-syntax">; </span><span class="comment-syntax"> in range 0 to </span><span class="extract"><span class="extract-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">unit_pair</span><span class="plain-syntax"> </span><span class="identifier-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</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">scaling_factor</span><span class="plain-syntax">; </span><span class="comment-syntax"> see discussion of scaling below</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure unit_sequence is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8"></a><b>§8. </b>Manipulating units like \({\rm m}^2\cdot{\rm kg}\cdot{\rm s}^{-2}\) looks
|
|
a little like manipulating formal polynomials in several variables, and of
|
|
course that isn't an accident. Another way of thinking of the above is that
|
|
we have a ring \(R\) of underlying numbers but that all arithmetic is done
|
|
in a larger ring. For each unit extend by \(R\) by a pair of formal
|
|
variables \(U_i\) and \(U_i^{-1}\), and then quotient by the ideal generated
|
|
by \(U_jU_j^{-1}\) (so that they are indeed reciprocals of each other, as
|
|
the notation suggests) and also by all of the derivations we know of. Thus
|
|
Inform calculates in the ring:
|
|
\(\) I = R[U_1, U_2, ..., U_n, U_1^{-1}, ..., U_n^{-1}] /
|
|
(U_1U_1^{-1}, U_2U_2^{-1}, ..., U_nU_n^{-1}, D_1, D_2, ..., D_i). \(\)
|
|
It does that in practice by eliminating all of the \(U_i\) and \(U_i^{-1}\)
|
|
which are derived, so that it's left with just
|
|
\(\) I = R[U_1, U_2, ..., U_k, U_1^{-1}, ..., U_k^{-1}] /
|
|
(U_1U_1^{-1}, U_2U_2^{-1}, ..., U_kU_k^{-1}). \(\)
|
|
</p>
|
|
|
|
<p class="commentary">For instance, given seconds, Watts and Joules,
|
|
\(\) I = R[{\rm s}, {\rm s}^{-1}, {\rm W}, {\rm W}^{-1}, {\rm J}, {\rm J}^{-1}]/
|
|
({\rm s}{\rm s}^{-1} = 1, {\rm W}{\rm W}^{-1}=1, {\rm J}{\rm J}^{-1} = 1,
|
|
{\rm s}{\rm W} = {\rm J}) \(\)
|
|
which by substituting all occurrences of {\rm J} can be reduced to:
|
|
\(\) I = R[{\rm s}, {\rm s}^{-1}, {\rm W}, {\rm W}^{-1}]/
|
|
({\rm s}{\rm s}^{-1} = 1, {\rm W}{\rm W}^{-1}=1). \(\)
|
|
Of course there are other ways to calculate \(I\) — we could have
|
|
eliminated any of the three units and kept the other two.
|
|
</p>
|
|
|
|
<p class="commentary">If the derivations were ever more complex than \(AB=C\), we might have to
|
|
use some elegant algorithms for calculating Gröbner bases in order to
|
|
determine \(I\). But Inform's syntax is such that the writer of the source
|
|
text gives us the simplest possible description of the ideal, so no such
|
|
fun occurs.
|
|
</p>
|
|
|
|
<p class="commentary">What does this ring look like? Because we are not allowed to add terms with
|
|
different powers of the variables, we only ever deal with monomials. Thus
|
|
we can form \(2{\rm W}{\rm s}^{-1} + 7{\rm W}{\rm s}^{-1}\), but Inform forbids
|
|
us to form (say) \(6{\rm J} + 7{\rm W}\). We can therefore picture the ring \(I\)
|
|
as a great mass of parallel copies of \(R\). Dimensionless values all live
|
|
in \(R\) itself, while energies all live in \(R.{\rm s}.{\rm W}\), powers in \(R.{\rm W}\)
|
|
and so on. Addition and subtraction slide values around within their own
|
|
parallel copies, but multiplication and division move them from one to
|
|
another. The computation \(v_1v_2\) is done in general by calculating the
|
|
numerical part (in \(R\)) at run-time, and the units (the choice of which
|
|
copy of \(R\)) at compile-time.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP9"></a><b>§9. </b>But enough abstraction: time for some arithmetic. Inform performs
|
|
checking whenever values from two different kinds are combined by any of
|
|
eight arithmetic operations, numbered as follows. The numbers must not
|
|
be changed without amending the definitions of "plus" and so on
|
|
in the Standard Rules.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">NO_OPERATIONS</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">PLUS_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax"> </span><span class="comment-syntax"> addition</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">MINUS_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="comment-syntax"> subtraction</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">TIMES_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="comment-syntax"> multiplication</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">DIVIDE_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax"> </span><span class="comment-syntax"> division</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">REMAINDER_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax"> </span><span class="comment-syntax"> remainder after division</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">APPROXIMATION_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax"> </span><span class="comment-syntax"> "X to the nearest Y"</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">ROOT_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax"> </span><span class="comment-syntax"> square root — a unary operation</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">REALROOT_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax"> </span><span class="comment-syntax"> real-valued square root — a unary operation</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">CUBEROOT_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax"> </span><span class="comment-syntax"> cube root — similarly unary</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">EQUALS_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax"> </span><span class="comment-syntax"> set equal — used only in equations</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">POWER_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax"> </span><span class="comment-syntax"> raise to integer power — used only in equations</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">UNARY_MINUS_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">11</span><span class="plain-syntax"> </span><span class="comment-syntax"> unary minus — used only in equations</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP10"></a><b>§10. </b>The following is associated with "total...", as in "the total weight
|
|
of things on the table", but that's a dodge used in the Standard Rules,
|
|
and for dimensional purposes we ignore it.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">TOTAL_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">12</span><span class="plain-syntax"> </span><span class="comment-syntax"> not really one of the above</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP11"></a><b>§11. </b>There are two reasons why Inform monitors arithmetic: to keep track of
|
|
how it changes kinds, and to preserve scaling factors.
|
|
</p>
|
|
|
|
<p class="commentary">We start from the principle that not every arithmetic operation can be done,
|
|
and that even when it can, the result may have a different kind than the
|
|
operand(s) had. For one thing, every arithmetic operation requires that its
|
|
operands are quasinumerical — Inform won't allow a text to be multiplied by
|
|
a sound effect. (Occasionally we have thought about allowing text to be
|
|
duplicated by multiplication — 2 times "zig" would be "zigzig", and
|
|
maybe similarly for lists — but it always seemed more likely to be used by
|
|
mistake than intentionally.)
|
|
</p>
|
|
|
|
<p class="commentary">Other restrictions are also applied. For instance, a time cannot be added
|
|
to a number, or vice versa; addition, subtraction and approximation require
|
|
both operands to have the same units.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP12"></a><b>§12. </b>Finally, scaling. Number is straightforwardly an integer kind:
|
|
it holds whole numbers. But other quasinumerical kinds can be stored
|
|
using scaled, fixed-point arithmetic. In general for each named unit
|
|
\(U\) (fundamental or derived) there is a positive integer \(k_U\) such that the
|
|
true value \(v\) is stored at run-time as the I6 integer \(k_U v\). We call
|
|
this the scaled value.
|
|
</p>
|
|
|
|
<p class="commentary">For example, if the text reads:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Force is a kind of value. 1N specifies a force scaled up by 1000.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">then \(k = 1000\) and the value 1N will be stored at run-time as <span class="extract"><span class="extract-syntax">1000</span></span>;
|
|
forces can thus be calculated to a true value accuracy of at best 0.001N,
|
|
stored at run-time as <span class="extract"><span class="extract-syntax">1</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">It must be emphasised that this is scaled, fixed-point arithmetic: there
|
|
are no mantissas or exponents. In such schemes the scale factor is usually
|
|
\(2^{16}\) or some similar power of 2, but here we want to use exactly the
|
|
scale factors laid out by the source text — partly because the user
|
|
knows best, partly so that it is unambiguous how to print values, partly
|
|
so that source text like "0.001N" determines an exact value rather than
|
|
being approximated by a binary equivalent.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP13"></a><b>§13. Prior kinds. </b>It turns out to be convenient to have a definition ordering of fundamental kinds,
|
|
which is completely unlike the \(\leq\) relation; it just places them in
|
|
order of creation.
|
|
</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::Dimensions::kind_prior</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::Dimensions::kind_prior</span></span>:<br/><a href="3-dmn.html#SP23_4">§23.4</a>, <a href="3-dmn.html#SP29_1">§29.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</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">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">B</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</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><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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</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">A</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</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><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>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-knd.html#SP8" class="function-link"><span class="function-syntax">Kinds::get_construct</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">A</span><span class="plain-syntax">)-></span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> < </span><a href="2-knd.html#SP8" class="function-link"><span class="function-syntax">Kinds::get_construct</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">B</span><span class="plain-syntax">)-></span><span class="identifier-syntax">allocation_id</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">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>§14. Multiplication lists. </b>The linked lists of multiplication rules begin empty for every kind:
|
|
</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::Dimensions::dim_initialise</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::Dimensions::dim_initialise</span></span>:<br/>Kind Constructors - <a href="2-kc2.html#SP6_1">§6.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">dimensional_rules</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-></span><span class="identifier-syntax">multiplications</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP15"></a><b>§15. </b>And this adds a new one to the relevant list:
|
|
</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::Dimensions::record_multiplication_rule</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::Dimensions::record_multiplication_rule</span></span>:<br/><a href="3-dmn.html#SP17">§17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rules</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP20" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dim_rules</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-></span><span class="element-syntax">multiplications</span><span class="plain-syntax">; </span><span class="identifier-syntax">dimr</span><span class="plain-syntax">; </span><span class="identifier-syntax">dimr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-></span><span class="element-syntax">next</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">dimr</span><span class="plain-syntax">-></span><span class="element-syntax">right</span><span class="plain-syntax"> == </span><span class="identifier-syntax">right</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DimensionRedundant_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">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-></span><span class="element-syntax">right</span><span class="plain-syntax"> = </span><span class="identifier-syntax">right</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-></span><span class="element-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">outcome</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">current_sentence</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</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">dimr_new</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-></span><span class="element-syntax">multiplications</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-></span><span class="identifier-syntax">multiplications</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP16"></a><b>§16. </b>The following loop-header macro iterates through the possible triples
|
|
\((L, R, O)\) of multiplication rules \(L\times R = O\).
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_MULTIPLICATIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">left_operand</span><span class="plain-syntax">, </span><span class="identifier-syntax">right_operand</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome_type</span><span class="plain-syntax">, </span><span class="identifier-syntax">wn</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rules</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</span><span class="plain-syntax">(</span><span class="identifier-syntax">left_operand</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP20" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dim_rules</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left_operand</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-></span><span class="element-syntax">multiplications</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">wn</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">)):-1,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">right_operand</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-></span><span class="element-syntax">right</span><span class="plain-syntax">):0,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome_type</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-></span><span class="element-syntax">outcome</span><span class="plain-syntax">):0;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">)):-1,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">right_operand</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-></span><span class="element-syntax">right</span><span class="plain-syntax">):0,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome_type</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-></span><span class="element-syntax">outcome</span><span class="plain-syntax">):0)</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP17"></a><b>§17. </b>And this is where the user asks for a multiplication to come out in a
|
|
particular way:
|
|
</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::Dimensions::dim_set_multiplication</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">right</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-knd.html#SP10" class="function-link"><span class="function-syntax">Kinds::is_proper_constructor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">)) ||</span>
|
|
<span class="plain-syntax"> (</span><a href="2-knd.html#SP10" class="function-link"><span class="function-syntax">Kinds::is_proper_constructor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">right</span><span class="plain-syntax">)) ||</span>
|
|
<span class="plain-syntax"> (</span><a href="2-knd.html#SP10" class="function-link"><span class="function-syntax">Kinds::is_proper_constructor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">))) {</span>
|
|
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DimensionNotBaseKOV_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">return</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><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</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-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">right</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-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">NonDimensional_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">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP15" class="function-link"><span class="function-syntax">Kinds::Dimensions::record_multiplication_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">)) && (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">)) && (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP29" class="function-link"><span class="function-syntax">Kinds::Dimensions::make_unit_derivation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP18"></a><b>§18. Unary operations. </b>All we need to know is which ones are unary, in fact, and:
|
|
</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::Dimensions::arithmetic_op_is_unary</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::Dimensions::arithmetic_op_is_unary</span></span>:<br/><a href="3-dmn.html#SP39">§39</a>, <a href="3-dmn.html#SP39_1">§39.1</a>, <a href="3-dmn.html#SP39_2">§39.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">op</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">op</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">CUBEROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REALROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNARY_MINUS_OPERATION:</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="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="SP19"></a><b>§19. Euclid's algorithm. </b>In my entire life, I believe this is the only time I have ever actually
|
|
used Euclid's algorithm for the GCD of two natural numbers. I've never
|
|
quite understood why textbooks take this as somehow the typical algorithm.
|
|
My maths students always find it a little oblique, despite the almost
|
|
trivial proof that it works. I find it hard to visualise myself, for that
|
|
matter. And then, consider that the average number of iterations \(\tau_n\),
|
|
in effect its running time, is known to be
|
|
$$ \tau_n = {{12\log 2}\over{\pi^2}}\log n + (4P + 5/2) + O(n^{-1/6+\epsilon) $$
|
|
for any \(\epsilon>0\), where \(P\) is defined in terms of an integral, Euler's
|
|
constant, and an evaluation of the derivative of the Riemann zeta function
|
|
— see D. E. Knuth, `Evaluation of Porter's Constant', reprinted in
|
|
"Selected Papers on Analysis of Algorithms" (Stanford: CSLI Lecture Notes
|
|
102, 2000). In practice, a shade under \(\log n\) steps, then, which is nicely
|
|
quick. But I don't look at the code and immediately see this, myself.
|
|
</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::Dimensions::gcd</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::Dimensions::gcd</span></span>:<br/><a href="3-dmn.html#SP20">§20</a><br/>Scaled Arithmetic Values - <a href="3-sav.html#SP8_2_2">§8.2.2</a>, <a href="3-sav.html#SP20_1_2">§20.1.2</a></span></button><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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</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">m</span><span class="plain-syntax"><1) || (</span><span class="identifier-syntax">n</span><span class="plain-syntax"><1)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"applied Kinds::Dimensions::gcd outside natural numbers"</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">TRUE</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">rem</span><span class="plain-syntax"> = </span><span class="identifier-syntax">m</span><span class="plain-syntax">%</span><span class="identifier-syntax">n</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">rem</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax"> = </span><span class="identifier-syntax">n</span><span class="plain-syntax">; </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rem</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP20"></a><b>§20. </b>The sequence of operation here is to reduce the risk of integer overflows
|
|
when multiplying <span class="extract"><span class="extract-syntax">m</span></span> by <span class="extract"><span class="extract-syntax">n</span></span>.
|
|
</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::Dimensions::lcm</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::Dimensions::lcm</span></span>:<br/><a href="3-dmn.html#SP39_4">§39.4</a></span></button><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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</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">m</span><span class="plain-syntax">/</span><a href="3-dmn.html#SP19" class="function-link"><span class="function-syntax">Kinds::Dimensions::gcd</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">m</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">))*</span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP21"></a><b>§21. Unit sequences. </b>Given a fundamental type \(B\), convert it to a unit sequence: \(B = B^1\), so we
|
|
get a sequence with a single pair: \(((B, 1))\). Uniquely, "number" is born
|
|
derived and dimensionless, though, so that comes out as the empty sequence.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::fundamental_unit_sequence</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::fundamental_unit_sequence</span></span>:<br/>Kind Constructors - <a href="2-kc2.html#SP6_1">§6.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</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">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">us</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">B</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">us</span><span class="plain-syntax">.</span><span class="identifier-syntax">no_unit_pairs</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">us</span><span class="plain-syntax">.</span><span class="identifier-syntax">unit_pairs</span><span class="plain-syntax">[0].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">us</span><span class="plain-syntax">.</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[0].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> redundant, but appeases </span><span class="extract"><span class="extract-syntax">gcc -O2</span></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">us</span><span class="plain-syntax">.</span><span class="identifier-syntax">no_unit_pairs</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">us</span><span class="plain-syntax">.</span><span class="identifier-syntax">unit_pairs</span><span class="plain-syntax">[0].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">; </span><span class="identifier-syntax">us</span><span class="plain-syntax">.</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[0].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</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">us</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP22"></a><b>§22. </b>As noted above, two units represent dimensionally equivalent physical
|
|
quantities if and only if they are identical, which makes comparison easy:
|
|
</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::Dimensions::compare_unit_sequences</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></span>:<br/><a href="3-dmn.html#SP29_4">§29.4</a>, <a href="3-dmn.html#SP39">§39</a>, <a href="3-dmn.html#SP39_3">§39.3</a><br/>Kind Checking - <a href="2-kc.html#SP9">§9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ik2</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">i</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">ik1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ik2</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">ik1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ik2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</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><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> != </span><span class="identifier-syntax">ik2</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</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><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><ik1-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax">, </span><span class="identifier-syntax">ik2</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax"> != </span><span class="identifier-syntax">ik2</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</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><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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP23"></a><b>§23. </b>We now have three fundamental operations we can perform on unit sequences.
|
|
First, we can multiply them: that is, we store in <span class="extract"><span class="extract-syntax">result</span></span> the unit
|
|
sequence representing \(X_1^{s_1}X_2^{s_2}\), where \(X_1\) and \(X_2\) are
|
|
represented by unit sequences <span class="extract"><span class="extract-syntax">us1</span></span> and <span class="extract"><span class="extract-syntax">us2</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">So the case \(s_1 = s_2 = 1\) represents multiplying \(X_1\) by \(X_2\), while
|
|
\(s_1 = 1, s_2 = -1\) represents dividing \(X_1\) by \(X_2\). But we can also
|
|
raise to higher powers.
|
|
</p>
|
|
|
|
<p class="commentary">Our method relies on noting that
|
|
\(\) X_1 = T_{11}^{p_{11}}\cdot T_{12}^{p_{12}}\cdots T_{1n}^{p_{1n}},\qquad
|
|
X_2 = T_{21}^{p_{21}}\cdot T_{22}^{p_{22}}\cdots T_{2m}^{p_{2m}} \(\)
|
|
where \(T_{11} < T_{12} < ... < T_{1n}\) and \(T_{21}<T_{22}<...<T_{2m}\). We
|
|
can therefore merge the two in a single pass.
|
|
</p>
|
|
|
|
<p class="commentary">On each iteration of the loop the variables <span class="extract"><span class="extract-syntax">i1</span></span> and <span class="extract"><span class="extract-syntax">i2</span></span> are our current
|
|
read positions in each sequence, while we are currently looking at the
|
|
unit pairs (<span class="extract"><span class="extract-syntax">t1</span></span>, <span class="extract"><span class="extract-syntax">m1</span></span>) and (<span class="extract"><span class="extract-syntax">t2</span></span>, <span class="extract"><span class="extract-syntax">m2</span></span>). The following symmetrical
|
|
algorithm holds on to each pair until the one from the other sequence has had
|
|
a chance to catch up with it, because we always deal with the pair with the
|
|
numerically lower <span class="extract"><span class="extract-syntax">t</span></span> first. This also proves that the <span class="extract"><span class="extract-syntax">results</span></span> sequence comes
|
|
out in numerical order.
|
|
</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::Dimensions::multiply_unit_sequences</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></span>:<br/><a href="3-dmn.html#SP25_2">§25.2</a>, <a href="3-dmn.html#SP29_2">§29.2</a>, <a href="3-dmn.html#SP29_4">§29.4</a>, <a href="3-dmn.html#SP39">§39</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s1</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s2</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</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">result</span><span class="plain-syntax"> == </span><span class="identifier-syntax">us1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">result</span><span class="plain-syntax"> == </span><span class="identifier-syntax">us2</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"result must be different structure"</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</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">i1</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">i2</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> read position in sequences 1, 2</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">p1</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> start with no current term from sequence 1</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> start with no current term from sequence 2</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_1" class="named-paragraph-link"><span class="named-paragraph">If we have no current term from sequence 1, and it hasn't run out, fetch a new one</span><span class="named-paragraph-number">23.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_2" class="named-paragraph-link"><span class="named-paragraph">If we have no current term from sequence 2, and it hasn't run out, fetch a new one</span><span class="named-paragraph-number">23.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t1</span><span class="plain-syntax">, </span><span class="identifier-syntax">t2</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">t1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> both sequences have now run out</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_3" class="named-paragraph-link"><span class="named-paragraph">Both terms refer to the same fundamental unit, so combine these into the result</span><span class="named-paragraph-number">23.3</span></a></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="named-paragraph-container code-font"><a href="3-dmn.html#SP23_4" class="named-paragraph-link"><span class="named-paragraph">The terms refer to different fundamental units, so copy the numerically lower one into the result</span><span class="named-paragraph-number">23.4</span></a></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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CREATIONS</span><span class="plain-syntax">, </span><span class="string-syntax">"Multiplication: $Q * $Q = $Q\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">us1</span><span class="plain-syntax">, </span><span class="identifier-syntax">us2</span><span class="plain-syntax">, </span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP23_1"></a><b>§23.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">If we have no current term from sequence 1, and it hasn't run out, fetch a new one</span><span class="named-paragraph-number">23.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">t1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">us1</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">i1</span><span class="plain-syntax"> < </span><span class="identifier-syntax">us1</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">t1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">us1</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i1</span><span class="plain-syntax">].</span><span class="identifier-syntax">fund_unit</span><span class="plain-syntax">; </span><span class="identifier-syntax">p1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">us1</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i1</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">; </span><span class="identifier-syntax">i1</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23">§23</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP23_2"></a><b>§23.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">If we have no current term from sequence 2, and it hasn't run out, fetch a new one</span><span class="named-paragraph-number">23.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">t2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">us2</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">i2</span><span class="plain-syntax"> < </span><span class="identifier-syntax">us2</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">t2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">us2</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i2</span><span class="plain-syntax">].</span><span class="identifier-syntax">fund_unit</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">us2</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i2</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">; </span><span class="identifier-syntax">i2</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23">§23</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP23_3"></a><b>§23.3. </b>So here the head of one sequence is \(T^{p_1}\) and the head of the other
|
|
is \(T^{p_2}\), so in the product we ought to see $(T^{p_1})^{s_1}\cdot
|
|
(T^{p_2})^{s_2} = T^{p_1s_1+p_2s_2}$. But we don't enter terms that have
|
|
cancelled out, that is, where \(p_1s_1+p_2s_2\) = 0.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Both terms refer to the same fundamental unit, so combine these into the result</span><span class="named-paragraph-number">23.3</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">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p1</span><span class="plain-syntax">*</span><span class="identifier-syntax">s1</span><span class="plain-syntax"> + </span><span class="identifier-syntax">p2</span><span class="plain-syntax">*</span><span class="identifier-syntax">s2</span><span class="plain-syntax">; </span><span class="comment-syntax"> combined power of </span><span class="extract"><span class="extract-syntax">t1</span></span><span class="comment-syntax"> </span>\(=\)<span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">t2</span></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</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">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_3_1" class="named-paragraph-link"><span class="named-paragraph">Trip a unit sequence overflow</span><span class="named-paragraph-number">23.3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">t1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">++].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">t1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">t2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> dispose of both terms as dealt with</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23">§23</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP23_4"></a><b>§23.4. </b>Otherwise we copy. By copying the numerically lower term, we can be sure
|
|
that it will never occur again in either sequence. So we can copy it straight
|
|
into the results.
|
|
</p>
|
|
|
|
<p class="commentary">The code is slightly warped by the fact that <span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span>, representing the
|
|
end of the sequence, happens to be numerically lower than all the valid
|
|
kinds. We don't want to make use of facts like that, so we write code
|
|
to deal with <span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span> explicitly.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">The terms refer to different fundamental units, so copy the numerically lower one into the result</span><span class="named-paragraph-number">23.4</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">t2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || ((</span><span class="identifier-syntax">t1</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) && (</span><a href="3-dmn.html#SP13" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_prior</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t1</span><span class="plain-syntax">, </span><span class="identifier-syntax">t2</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">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_3_1" class="named-paragraph-link"><span class="named-paragraph">Trip a unit sequence overflow</span><span class="named-paragraph-number">23.3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">t1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">++].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p1</span><span class="plain-syntax">*</span><span class="identifier-syntax">s1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">t1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> dispose of the head of sequence 1 as dealt with</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">t1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || ((</span><span class="identifier-syntax">t2</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) && (</span><a href="3-dmn.html#SP13" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_prior</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t2</span><span class="plain-syntax">, </span><span class="identifier-syntax">t1</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">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_3_1" class="named-paragraph-link"><span class="named-paragraph">Trip a unit sequence overflow</span><span class="named-paragraph-number">23.3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">t2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">++].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p2</span><span class="plain-syntax">*</span><span class="identifier-syntax">s2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">t2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> dispose of the head of sequence 1 as dealt with</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unit pairs disarrayed"</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23">§23</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP23_3_1"></a><b>§23.3.1. </b>For reasons explained above, this is really never going to happen by
|
|
accident, but we'll be careful:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Trip a unit sequence overflow</span><span class="named-paragraph-number">23.3.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">UnitSequenceOverflow_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">return</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23_3">§23.3</a>, <a href="3-dmn.html#SP23_4">§23.4</a> (twice).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP24"></a><b>§24. </b>The second operation is taking roots.
|
|
</p>
|
|
|
|
<p class="commentary">Surprisingly, perhaps, it's much easier to compute \(\sqrt{X}\) or
|
|
\(^{3}\sqrt{X}\) for any unit \(X\) — it's just that it can't always be done.
|
|
Inform does not permit non-integer powers of units, so for instance
|
|
\(\sqrt{{\rm time}}\) does not exist, whereas \(\sqrt{{\rm length}^2\cdot{\rm mass}^{-2}}\)
|
|
does. Square roots exist if each power in the sequence is even, cube roots
|
|
exist if each is divisible by 3. We return <span class="extract"><span class="extract-syntax">TRUE</span></span> or <span class="extract"><span class="extract-syntax">FALSE</span></span> according to
|
|
whether the root could be taken, and if <span class="extract"><span class="extract-syntax">FALSE</span></span> then the contents of
|
|
<span class="extract"><span class="extract-syntax">result</span></span> are undefined.
|
|
</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::Dimensions::root_unit_sequence</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></span>:<br/><a href="3-dmn.html#SP39">§39</a>, <a href="3-dmn.html#SP40">§40</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pow</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</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">us</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</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><span class="identifier-syntax">result</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">us</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">i</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><result-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</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">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">) % </span><span class="identifier-syntax">pow</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</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><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">)/</span><span class="identifier-syntax">pow</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">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP25"></a><b>§25. </b>The final operation on unit sequences is substitution. Given a fundamental type
|
|
\(B\), we substitute \(B = K_D\) into an existing unit sequence \(K_E\). (This is
|
|
used when \(B\) is becoming a derived type — once we discover that \(B=K_D\),
|
|
we are no longer allowed to keep \(B\) in any unit sequence.)
|
|
</p>
|
|
|
|
<p class="commentary">We simply search for \(B^p\), and if we find it, we remove it and then
|
|
multiply by \(K_D^p\).
|
|
</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::Dimensions::dim_substitute</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::dim_substitute</span></span>:<br/><a href="3-dmn.html#SP29_3">§29.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">derived</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">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">found</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">existing</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><existing-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax">, </span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP25_1" class="named-paragraph-link"><span class="named-paragraph">Remove the B term from the existing sequence</span><span class="named-paragraph-number">25.1</span></a></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">found</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP25_2" class="named-paragraph-link"><span class="named-paragraph">Multiply the existing sequence by a suitable power of B's derivation</span><span class="named-paragraph-number">25.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP25_1"></a><b>§25.1. </b>We shuffle the remaining terms in the sequence down by one, overwriting B:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove the B term from the existing sequence</span><span class="named-paragraph-number">25.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">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=</span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="function-syntax"><existing-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">+1];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">--;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP25">§25</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP25_2"></a><b>§25.2. </b>We now multiply by \(K_D^p\).
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Multiply the existing sequence by a suitable power of B's derivation</span><span class="named-paragraph-number">25.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">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">derived</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">, &</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP25">§25</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP26"></a><b>§26. </b>For reasons which will be explained below, a unit sequence also has
|
|
a scale factor associated with it:
|
|
</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::Dimensions::us_get_scaling_factor</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::us_get_scaling_factor</span></span>:<br/>Using Kinds - <a href="2-uk.html#SP19">§19</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us</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">us</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">us</span><span class="plain-syntax">-></span><span class="element-syntax">scaling_factor</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP27"></a><b>§27. </b>That just leaves, as usual, indexing...
|
|
</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::Dimensions::index_unit_sequence</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::index_unit_sequence</span></span>:<br/><a href="3-dmn.html#SP31_2">§31.2</a><br/>Describing Kinds - <a href="2-dk.html#SP24_1">§24.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deriv</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">briefly</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">deriv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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">deriv</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </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">"dimensionless"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</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">j</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="function-syntax"><deriv-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fundamental</span><span class="plain-syntax"> = </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</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">power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="element-syntax">power</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">briefly</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">j</span><span class="plain-syntax">>0) </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">"("</span><span class="plain-syntax">);</span>
|
|
<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="plain-syntax"> </span><span class="identifier-syntax">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</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">else</span>
|
|
<span class="plain-syntax"> </span><a href="2-dk.html#SP22" class="function-link"><span class="function-syntax">Kinds::Textual::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</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">power</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<sup>%d</sup>"</span><span class="plain-syntax">, </span><span class="identifier-syntax">power</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">j</span><span class="plain-syntax">>0) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" times "</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">power</span><span class="plain-syntax"> < </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">power</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">power</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"reciprocal of "</span><span class="plain-syntax">); }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP1" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</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">"%W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</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">power</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</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="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" squared"</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="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" cubed"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" to the power %d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">power</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="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP28"></a><b>§28. </b>...and logging.
|
|
</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::Dimensions::logger</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::logger</span></span>:<br/>Kinds Module - <a href="1-km.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vUS</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deriv</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vUS</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">deriv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<null-us>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</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">deriv</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </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">"dimensionless"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="function-syntax"><deriv-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</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">j</span><span class="plain-syntax">>0) </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">"(%u)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</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">deriv</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="identifier-syntax">power</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</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">deriv</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP29"></a><b>§29. Performing derivations. </b>The following is called when the user specifies that \(L\) times \(R\) specifies
|
|
an \(O\). These are required all to be quasinumerical: any of the three might
|
|
be either a fundamental unit (so far) or a derived unit (already).
|
|
</p>
|
|
|
|
<p class="commentary">If two or more are fundamental units, we have a choice. That is, suppose we have
|
|
created three kinds already: mass, acceleration, force. Then we read:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Mass times acceleration specifies a force.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">We could make this true in any of three ways: keep M and A as fundamental units
|
|
and derive F from them, keep A and F as fundamental units and derive M from those,
|
|
or keep M and F while deriving A. Inform always chooses the most recently
|
|
created unit as the one to derive, on the grounds that the source text has
|
|
probably set things out with what the user thinks are the most fundamental
|
|
units first.
|
|
</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::Dimensions::make_unit_derivation</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::make_unit_derivation</span></span>:<br/><a href="3-dmn.html#SP17">§17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[3];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">left</span><span class="plain-syntax">; </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">right</span><span class="plain-syntax">; </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[2] = </span><span class="identifier-syntax">outcome</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">newest_term</span><span class="plain-syntax"> = -1;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP29_1" class="named-paragraph-link"><span class="named-paragraph">Find which (if any) of the three units is the newest-made fundamental unit</span><span class="named-paragraph-number">29.1</span></a></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">newest_term</span><span class="plain-syntax"> >= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">derivation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP29_2" class="named-paragraph-link"><span class="named-paragraph">Derive the newest one by rearranging the equation in terms of the other two</span><span class="named-paragraph-number">29.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP29_3" class="named-paragraph-link"><span class="named-paragraph">Substitute this new derivation to eliminate this fundamental unit from other sequences</span><span class="named-paragraph-number">29.3</span></a></span><span class="plain-syntax">;</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="3-dmn.html#SP29_4" class="named-paragraph-link"><span class="named-paragraph">Check this derivation to make sure it is redundant, not contradictory</span><span class="named-paragraph-number">29.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP29_1"></a><b>§29.1. </b>Data type IDs are allocated in creation order, so "newest" means largest ID.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find which (if any) of the three units is the newest-made fundamental unit</span><span class="named-paragraph-number">29.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">i</span><span class="plain-syntax">; </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">max</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">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax"><3; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-dmn.html#SP13" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_prior</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">max</span><span class="plain-syntax">, </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">])) && (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::test_if_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">newest_term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">max</span><span class="plain-syntax"> = </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP29">§29</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP29_2"></a><b>§29.2. </b>We need to ensure that the user's multiplication rule is henceforth true,
|
|
and we do that by fixing the newest unit to make it so.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Derive the newest one by rearranging the equation in terms of the other two</span><span class="named-paragraph-number">29.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">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">ky</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sx</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">sy</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</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">newest_term</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="comment-syntax"> here </span>\(L\)<span class="comment-syntax"> is newest and we derive </span>\(L = R^{-1}O\)
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1]); </span><span class="identifier-syntax">sx</span><span class="plain-syntax"> = -1;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ky</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[2]); </span><span class="identifier-syntax">sy</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">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="constant-syntax">1</span><span class="plain-syntax">: </span><span class="comment-syntax"> here </span>\(R\)<span class="comment-syntax"> is newest and we derive </span>\(R = L^{-1}O\)
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0]); </span><span class="identifier-syntax">sx</span><span class="plain-syntax"> = -1;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ky</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[2]); </span><span class="identifier-syntax">sy</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">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="constant-syntax">2</span><span class="plain-syntax">: </span><span class="comment-syntax"> here </span>\(O\)<span class="comment-syntax"> is newest and we derive </span>\(O = LR\)
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0]); </span><span class="identifier-syntax">sx</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">ky</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1]); </span><span class="identifier-syntax">sy</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">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">derivation</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">newest_term</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kx</span><span class="plain-syntax">, </span><span class="identifier-syntax">sx</span><span class="plain-syntax">, </span><span class="identifier-syntax">ky</span><span class="plain-syntax">, </span><span class="identifier-syntax">sy</span><span class="plain-syntax">, &</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> *</span><span class="identifier-syntax">derivation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::now_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">newest_term</span><span class="plain-syntax">]);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP29">§29</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP29_3"></a><b>§29.3. </b>Later in Inform's run, when we start compiling code, many more unit sequences
|
|
will exist on a temporary basis — as part of the kinds for intermediate results
|
|
in calculations — but early on, when we're here, the only unit sequences made
|
|
are the derivations of the units. So it is easy to cover all of them.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Substitute this new derivation to eliminate this fundamental unit from other sequences</span><span class="named-paragraph-number">29.3</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</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><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><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">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP25" class="function-link"><span class="function-syntax">Kinds::Dimensions::dim_substitute</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">newest_term</span><span class="plain-syntax">], </span><span class="identifier-syntax">derivation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP29">§29</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP29_4"></a><b>§29.4. </b>If we have \(AB = C\) but all three of \(A\), \(B\), \(C\) are already derived,
|
|
that puts us in a bind. Their definitions are fixed already, so we can't
|
|
simply force the equation to come true by fixing one of them. That means
|
|
either the derivation is redundant — because it's already true that
|
|
\(AB = C\) — or contradictory — because we know \(AB\neq C\). We silently
|
|
allow a redundancy, as it may have been put in for clarity, or so that
|
|
the user can check the consistency of his own definitions, or to make
|
|
the Kinds index page more helpful. But we must reject a contradiction.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check this derivation to make sure it is redundant, not contradictory</span><span class="named-paragraph-number">29.4</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">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">product</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0]), </span><span class="constant-syntax">1</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1]), </span><span class="constant-syntax">1</span><span class="plain-syntax">, &</span><span class="identifier-syntax">product</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP22" class="function-link"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">product</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[2])) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DimensionsInconsistent_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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP29">§29</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP30"></a><b>§30. Classifying the units. </b>Some of the derived units are dimensionless, others not. Number
|
|
is always dimensionless; and any unit whose derivation is the empty
|
|
unit sequence must be dimensionless.
|
|
</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::Dimensions::dimensionless</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></span>:<br/><a href="3-dmn.html#SP31_2">§31.2</a>, <a href="3-dmn.html#SP32">§32</a>, <a href="3-dmn.html#SP39_1">§39.1</a>, <a href="3-dmn.html#SP40">§40</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</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><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</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><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_real_number</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><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</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><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span></a><span class="plain-syntax">(</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span></span>:<br/><a href="3-dmn.html#SP39_2">§39.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us</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">us</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">us</span><span class="plain-syntax">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</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">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="SP31"></a><b>§31. </b>Using these definitions, we can now print analyses of the units into the
|
|
index and the debugging log.
|
|
</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::Dimensions::index_dimensional_rules</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"hr"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP31_1" class="named-paragraph-link"><span class="named-paragraph">Index the rubric about quasinumerical kinds</span><span class="named-paragraph-number">31.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP31_2" class="named-paragraph-link"><span class="named-paragraph">Index the table of quasinumerical kinds</span><span class="named-paragraph-number">31.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP31_3" class="named-paragraph-link"><span class="named-paragraph">Index the table of multiplication rules</span><span class="named-paragraph-number">31.3</span></a></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="SP31_1"></a><b>§31.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the rubric about quasinumerical kinds</span><span class="named-paragraph-number">31.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">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"a"</span><span class="plain-syntax">, </span><span class="string-syntax">"calculator"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_plain_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::first_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">HTML_TAG_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"img"</span><span class="plain-syntax">, </span><span class="string-syntax">"border=0 src=inform:/doc_images/calc2.png"</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">"&nbsp;"</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">"Kinds of value marked with the <b>calculator symbol</b> are numerical - "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"these are values we can add, multiply and so on. The range of these "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"numbers depends on the Format setting for the project (Glulx format "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"supports much higher numbers than Z-code)."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_row</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">§31</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP31_2"></a><b>§31.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the table of quasinumerical kinds</span><span class="named-paragraph-number">31.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="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_plain_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::first_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<b>kind of value</b>"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<b>minimum</b>"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<b>maximum</b>"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<b>dimensions</b>"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_row</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</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><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><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><a href="2-knd.html#SP9" class="function-link"><span class="function-syntax">Kinds::is_intermediate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::first_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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="3-dmn.html#SP31_2_1" class="named-paragraph-link"><span class="named-paragraph">Index the minimum positive value for a quasinumerical kind</span><span class="named-paragraph-number">31.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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="3-dmn.html#SP31_2_2" class="named-paragraph-link"><span class="named-paragraph">Index the maximum positive value for a quasinumerical kind</span><span class="named-paragraph-number">31.2.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<i>dimensionless</i>"</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">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deriv</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP27" class="function-link"><span class="function-syntax">Kinds::Dimensions::index_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_row</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">§31</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP31_2_1"></a><b>§31.2.1. </b>At run-time, the minimum positive value is of course <span class="extract"><span class="extract-syntax">1</span></span>, but because of
|
|
scaling this can appear to be much lower.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the minimum positive value for a quasinumerical kind</span><span class="named-paragraph-number">31.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><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"1"</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">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP39" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_index_minimum_value</span></a><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">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) > </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">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</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">LiteralPatterns::index_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::list_of_literal_forms</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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31_2">§31.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP31_2_2"></a><b>§31.2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the maximum positive value for a quasinumerical kind</span><span class="named-paragraph-number">31.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><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</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">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"32767"</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">"2147483647"</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">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP39" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_index_maximum_value</span></a><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">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) > </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">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</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">TargetVMs::is_16_bit</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::vm</span><span class="plain-syntax">()))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::index_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::list_of_literal_forms</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="constant-syntax">32767</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">LiteralPatterns::index_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::list_of_literal_forms</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="constant-syntax">2147483647</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="3-dmn.html#SP31_2">§31.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP31_3"></a><b>§31.3. </b>This is simply a table of all the multiplications declared in the source
|
|
text, sorted into kind order of left and then right operand.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the table of multiplication rules</span><span class="named-paragraph-number">31.3</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, *</span><span class="identifier-syntax">O</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">NP</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_MULTIPLICATIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="identifier-syntax">wn</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">NP</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">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</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">"This is how multiplication changes kinds:"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_plain_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::first_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</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">wn</span><span class="plain-syntax"> >= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">Index::link</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">wn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"808080"</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">" x "</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"808080"</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="identifier-syntax">HTML::end_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</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">"&nbsp;&nbsp;&nbsp;&nbsp;"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">LiteralPatterns::index_benchmark_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"808080"</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">" x "</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::index_benchmark_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"808080"</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="identifier-syntax">HTML::end_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::index_benchmark_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_row</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">NP</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">HTML::end_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">); </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">); }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">§31</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP32"></a><b>§32. </b>A simpler format for the debugging log, which is printed when we ask for
|
|
the internal "dimensions" test:
|
|
</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::Dimensions::log_unit_analysis</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Dimensionless: "</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">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</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><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%u"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">); }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\nBase units: "</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">c</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">LOOP_OVER_BASE_KINDS</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><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="3-dmn.html#SP32" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_is_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</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-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><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">c</span><span class="plain-syntax">++ > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%u"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">); }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\nDerived units:\n"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</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><a href="3-dmn.html#SP32" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_is_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) && (</span><a href="2-knd.html#SP9" class="function-link"><span class="function-syntax">Kinds::is_intermediate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</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">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deriv</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%u = $Q\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_is_derived</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</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">if</span><span class="plain-syntax"> (</span><a href="2-knd.html#SP9" class="function-link"><span class="function-syntax">Kinds::is_intermediate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</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><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::test_if_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</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">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="SP33"></a><b>§33. Scaling. </b>Recall that every quasinumerical kind \(U\) has a scale factor \(k_U\), by
|
|
default 1 and always \(\geq 1\), such that the true value \(v\) is represented
|
|
at runtime as the I6 integer \(k_U v\). For instance, if length is measured
|
|
in metres but has a scale factor of 1000 then the I6 integer 1 means the
|
|
true value 1mm, 10 means 1cm, 1000 means 1m. This I6 integer is called
|
|
the scaled value \(s\), and to reiterate, \(s = k_U v\).
|
|
</p>
|
|
|
|
<p class="commentary">Scaled values are convenient, and they have no effect on how we add, subtract,
|
|
approximate (that is, round off) or take remainder after division. If we
|
|
have true values \(v_1\) and \(v_2\) with scaled values \(s_1\) and \(s_2\),
|
|
and \(s_o\) is the scaled value for true value \(v_1+v_2\), then
|
|
</p>
|
|
|
|
<p class="commentary">$$ s_1 + s_2 = k_Uv_1 + k_Uv_2 = k_U(v_1+v_2) = s_o. $$
|
|
</p>
|
|
|
|
<p class="commentary">So ordinary I6 <span class="extract"><span class="extract-syntax">+</span></span> at run-time correctly adds scaled values. But that's
|
|
not true for all operations, and this is where we deal with that.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP34"></a><b>§34. </b>First, multiplication. This time the values \(v_1\) and \(v_2\) may have
|
|
different kinds, which we'll call \(X\) and \(Y\), and the result in general
|
|
will be a third kind, which we'll call \(O\) (for outcome). Then:
|
|
</p>
|
|
|
|
<p class="commentary">$$ s_1s_2 = k_Xv_1\cdot k_Yv_2 = k_Ov_1v_2\cdot\left({{k_Xk_Y}\over{k_O}}\right) = s_o\cdot\left({{k_Xk_Y}\over{k_O}}\right) $$
|
|
</p>
|
|
|
|
<p class="commentary">so that simply multiplying the scaled values produces an answer which is
|
|
too large by a factor of \(k_Xk_Y/k_O\). We need to correct for that, which
|
|
we do either by dividing by this factor or multiplying by its reciprocal.
|
|
</p>
|
|
|
|
<p class="commentary">This is all a little delicate since rounding errors may be an issue and
|
|
since \(k_Xk_Y/k_O\) is itself evaluated in integer arithmetic. In an ideal
|
|
world we might use the same \(k\) for many units (e.g., \(k=1000\) throughout)
|
|
and then of course this cancels to just \(1000\). But in practice people
|
|
won't always do this — they may use some Babylonian, base 60, units, such
|
|
as minutes and degrees, for instance, where \(k=3600\) would be more natural.
|
|
</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::Dimensions::kind_rescale_multiplication</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</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">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">TIMES_OPERATION</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">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</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_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</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_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</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">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_O</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">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</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">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_O</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">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<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::Dimensions::kind_rescale_multiplication_emit_op</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</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">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">TIMES_OPERATION</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">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</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_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</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_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</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">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_O</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="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">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_O</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="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">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_multiplication_emit_factor</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</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">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">TIMES_OPERATION</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">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</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_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</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_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</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">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_O</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_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_O</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_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_Y</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="SP35"></a><b>§35. </b>Second, division, which is similar.
|
|
\(\) {{s_1}\over{s_2}} = {{k_Xv_1}\over{k_Yv_2}} = k_O{{v_1}\over{v_2}}\cdot\left({{k_X}\over{k_Ok_Y}}\right)
|
|
= s_o\cdot\left({{k_X}\over{k_Ok_Y}\right) \(\)
|
|
so this time the excess to correct is a factor of \(k_X/k_Ok_Y\).
|
|
</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::Dimensions::kind_rescale_division</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</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">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">DIVIDE_OPERATION</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">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</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_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</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_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_X</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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_X</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">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<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::Dimensions::kind_rescale_division_emit_op</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</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">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">DIVIDE_OPERATION</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">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</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_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</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_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_X</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="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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_X</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="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">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_division_emit_factor</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</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">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">DIVIDE_OPERATION</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">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</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_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</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_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_X</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_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_X</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_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_Y</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="SP36"></a><b>§36. </b>Third, the taking of \(p\)th roots, at any rate for \(p=2\) or \(p=3\).
|
|
</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::Dimensions::kind_rescale_root</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">power</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">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">ROOT_OPERATION</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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">CUBEROOT_OPERATION</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">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</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_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP36_1" class="named-paragraph-link"><span class="named-paragraph">Apply a scaling correction for square roots</span><span class="named-paragraph-number">36.1</span></a></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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP36_2" class="named-paragraph-link"><span class="named-paragraph">Apply a scaling correction for cube roots</span><span class="named-paragraph-number">36.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can only scale square and cube roots"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP36_1"></a><b>§36.1. </b>For square roots,
|
|
\(\) \sqrt{s} = \sqrt{k_Xv} = \sqrt{k_X}\sqrt{v} = k_O\sqrt{v}\cdot
|
|
\left({{\sqrt{k_X}}\over{k_O}}\right) = s_o \cdot
|
|
\left({{\sqrt{k_X}}\over{k_O}}\right) \(\)
|
|
and now the overestimate is a factor of \(k = \sqrt{k_X}/k_O\). However,
|
|
rather than calculating \(k\sqrt{x}\) we calculate \(\sqrt{k^2 x}\), since
|
|
this way accuracy losses in taking the square root are much reduced.
|
|
Therefore this scaling operating is to be performed inside the root
|
|
function, not outside, and it scales by \(k^2\) not \(k\):
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Apply a scaling correction for square roots</span><span class="named-paragraph-number">36.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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_X</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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_X</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">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">));</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP36">§36</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP36_2"></a><b>§36.2. </b>For cube roots,
|
|
\(\) {}^3\sqrt{s} = {}^3\sqrt{k_Xv} = {}^3\sqrt{k_X}{}^3\sqrt{v} = k_O{}^3\sqrt{v}\cdot
|
|
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) = s_o\cdot
|
|
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) \(\)
|
|
and the overestimate is \(k = {}^3\sqrt{k_X}/k_O\). Scaling once again within
|
|
the rooting function, we scale by \(k^3\):
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Apply a scaling correction for cube roots</span><span class="named-paragraph-number">36.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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_X</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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_X</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">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">));</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP36">§36</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP37"></a><b>§37. </b></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::Dimensions::kind_rescale_root_emit_op</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">power</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">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">ROOT_OPERATION</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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">CUBEROOT_OPERATION</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">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</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_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP37_1" class="named-paragraph-link"><span class="named-paragraph">Emit a scaling correction for square roots</span><span class="named-paragraph-number">37.1</span></a></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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP37_2" class="named-paragraph-link"><span class="named-paragraph">Emit a scaling correction for cube roots</span><span class="named-paragraph-number">37.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can only scale square and cube roots"</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="SP37_1"></a><b>§37.1. </b>For square roots,
|
|
\(\) \sqrt{s} = \sqrt{k_Xv} = \sqrt{k_X}\sqrt{v} = k_O\sqrt{v}\cdot
|
|
\left({{\sqrt{k_X}}\over{k_O}}\right) = s_o \cdot
|
|
\left({{\sqrt{k_X}}\over{k_O}}\right) \(\)
|
|
and now the overestimate is a factor of \(k = \sqrt{k_X}/k_O\). However,
|
|
rather than calculating \(k\sqrt{x}\) we calculate \(\sqrt{k^2 x}\), since
|
|
this way accuracy losses in taking the square root are much reduced.
|
|
Therefore this scaling operating is to be performed inside the root
|
|
function, not outside, and it scales by \(k^2\) not \(k\):
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit a scaling correction for square roots</span><span class="named-paragraph-number">37.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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_X</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="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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_X</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="identifier-syntax">Produce::down</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="3-dmn.html#SP37">§37</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP37_2"></a><b>§37.2. </b>For cube roots,
|
|
\(\) {}^3\sqrt{s} = {}^3\sqrt{k_Xv} = {}^3\sqrt{k_X}{}^3\sqrt{v} = k_O{}^3\sqrt{v}\cdot
|
|
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) = s_o\cdot
|
|
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) \(\)
|
|
and the overestimate is \(k = {}^3\sqrt{k_X}/k_O\). Scaling once again within
|
|
the rooting function, we scale by \(k^3\):
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit a scaling correction for cube roots</span><span class="named-paragraph-number">37.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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_X</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="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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_X</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="identifier-syntax">Produce::down</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="3-dmn.html#SP37">§37</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP38"></a><b>§38. </b></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::Dimensions::kind_rescale_root_emit_factor</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">power</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">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">ROOT_OPERATION</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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">CUBEROOT_OPERATION</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">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</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_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP38_1" class="named-paragraph-link"><span class="named-paragraph">Emit factor for a scaling correction for square roots</span><span class="named-paragraph-number">38.1</span></a></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">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP38_2" class="named-paragraph-link"><span class="named-paragraph">Emit factor for a scaling correction for cube roots</span><span class="named-paragraph-number">38.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can only scale square and cube roots"</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="SP38_1"></a><b>§38.1. </b>For square roots,
|
|
\(\) \sqrt{s} = \sqrt{k_Xv} = \sqrt{k_X}\sqrt{v} = k_O\sqrt{v}\cdot
|
|
\left({{\sqrt{k_X}}\over{k_O}}\right) = s_o \cdot
|
|
\left({{\sqrt{k_X}}\over{k_O}}\right) \(\)
|
|
and now the overestimate is a factor of \(k = \sqrt{k_X}/k_O\). However,
|
|
rather than calculating \(k\sqrt{x}\) we calculate \(\sqrt{k^2 x}\), since
|
|
this way accuracy losses in taking the square root are much reduced.
|
|
Therefore this scaling operating is to be performed inside the root
|
|
function, not outside, and it scales by \(k^2\) not \(k\):
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit factor for a scaling correction for square roots</span><span class="named-paragraph-number">38.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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_X</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_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_X</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_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</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="3-dmn.html#SP38">§38</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP38_2"></a><b>§38.2. </b>For cube roots,
|
|
\(\) {}^3\sqrt{s} = {}^3\sqrt{k_Xv} = {}^3\sqrt{k_X}{}^3\sqrt{v} = k_O{}^3\sqrt{v}\cdot
|
|
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) = s_o\cdot
|
|
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) \(\)
|
|
and the overestimate is \(k = {}^3\sqrt{k_X}/k_O\). Scaling once again within
|
|
the rooting function, we scale by \(k^3\):
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit factor for a scaling correction for cube roots</span><span class="named-paragraph-number">38.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">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> > </span><span class="identifier-syntax">k_X</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_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> < </span><span class="identifier-syntax">k_X</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_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</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="3-dmn.html#SP38">§38</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39"></a><b>§39. Arithmetic on kinds. </b>We are finally able to provide our central routine, the one providing a service
|
|
for the rest of Inform. Given <span class="extract"><span class="extract-syntax">K1</span></span> and <span class="extract"><span class="extract-syntax">K2</span></span>, we return the kind resulting
|
|
from applying arithmetic operation <span class="extract"><span class="extract-syntax">op</span></span>, or <span class="extract"><span class="extract-syntax">NULL</span></span> if the operation cannot
|
|
meaningfully be applied. In the case where <span class="extract"><span class="extract-syntax">op</span></span> is a unary operation, <span class="extract"><span class="extract-syntax">K2</span></span>
|
|
has no significance and should be <span class="extract"><span class="extract-syntax">NULL</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">The kinds here are called operands, because they are what will be operated on.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></span>:<br/><a href="3-dmn.html#SP34">§34</a>, <a href="3-dmn.html#SP35">§35</a>, <a href="3-dmn.html#SP36">§36</a>, <a href="3-dmn.html#SP37">§37</a>, <a href="3-dmn.html#SP38">§38</a>, <a href="3-dmn.html#SP40">§40</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K1</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">op</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">K1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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><a href="3-dmn.html#SP18" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">op</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">K2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">operand1</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</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">operand1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">operand2</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-dmn.html#SP18" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">op</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">operand2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</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">op</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">PLUS_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MINUS_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EQUALS_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">APPROXIMATION_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP22" class="function-link"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand2</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">;</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">return</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">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REMAINDER_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNARY_MINUS_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">;</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">ROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP24" class="function-link"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">, &</span><span class="identifier-syntax">result</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">return</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">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">REALROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP24" class="function-link"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">, &</span><span class="identifier-syntax">result</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">return</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">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">CUBEROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP24" class="function-link"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">3</span><span class="plain-syntax">, &</span><span class="identifier-syntax">result</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">return</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">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">TIMES_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand2</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, &</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</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">DIVIDE_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand2</span><span class="plain-syntax">, -1, &</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_1" class="named-paragraph-link"><span class="named-paragraph">Handle calculations entirely between dimensionless units more delicately</span><span class="named-paragraph-number">39.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_2" class="named-paragraph-link"><span class="named-paragraph">Handle the case of a dimensionless result</span><span class="named-paragraph-number">39.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_3" class="named-paragraph-link"><span class="named-paragraph">Identify the result as a known kind, if possible</span><span class="named-paragraph-number">39.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_4" class="named-paragraph-link"><span class="named-paragraph">And otherwise create a kind as the intermediate result of a calculation</span><span class="named-paragraph-number">39.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP39_1"></a><b>§39.1. </b>If <span class="extract"><span class="extract-syntax">result</span></span> is the empty unit sequence, we'll identify it as a number,
|
|
because number is the lowest type ID representing a dimensionless unit.
|
|
Usually that's good: for instance, it says that a frequency times a time
|
|
is a number, and not some more exotic dimensionless quantity like an angle.
|
|
</p>
|
|
|
|
<p class="commentary">But it's not so good when the calculation is not really physical at all, but
|
|
purely mathematical, and all we are doing is working on dimensionless units.
|
|
For instance, if take an angle \(\theta\) and double it to \(2\theta\), we don't
|
|
want Inform to say the result is number — we want \(2\theta\) to be
|
|
another angle. So we make an exception.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle calculations entirely between dimensionless units more delicately</span><span class="named-paragraph-number">39.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><a href="3-dmn.html#SP18" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">op</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">op</span><span class="plain-syntax"> == </span><span class="constant-syntax">REALROOT_OPERATION</span><span class="plain-syntax">) && (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</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">K_real_number</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K1</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><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">)) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">))) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">, </span><span class="identifier-syntax">K2</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K1</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="3-dmn.html#SP39">§39</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39_2"></a><b>§39.2. </b>It's also possible to get a dimensionless result by, for example, dividing
|
|
a mass by another mass, and we need to be careful to keep track of whether
|
|
we're using real or integer arithmetic: 1500.0m divided by 10.0m must be
|
|
150.0, not 150.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle the case of a dimensionless result</span><span class="named-paragraph-number">39.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><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">result</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP18" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">op</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-fv.html#SP3" class="function-link"><span class="function-syntax">Kinds::FloatingPoint::uses_floating_point</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_real_number</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">K_number</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><a href="3-fv.html#SP3" class="function-link"><span class="function-syntax">Kinds::FloatingPoint::uses_floating_point</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">)) ||</span>
|
|
<span class="plain-syntax"> (</span><a href="3-fv.html#SP3" class="function-link"><span class="function-syntax">Kinds::FloatingPoint::uses_floating_point</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_real_number</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">K_number</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="3-dmn.html#SP39">§39</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39_3"></a><b>§39.3. </b>If we've produced the right combination of fundamental units to make one of the
|
|
named units, then we return that as an atomic kind. For instance, maybe we
|
|
divided a velocity by a time, and now we find that we have ${\rm m}\cdot
|
|
{\rm s}^{-2}$, which turns out to have a name: acceleration.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Identify the result as a known kind, if possible</span><span class="named-paragraph-number">39.3</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</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><a href="3-dmn.html#SP22" class="function-link"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">result</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP39">§39</a>, <a href="3-dmn.html#SP40">§40</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39_4"></a><b>§39.4. </b>Otherwise the <span class="extract"><span class="extract-syntax">result</span></span> is a unit sequence which doesn't have a name, so
|
|
we store it as an intermediate kind, representing a temporary value living
|
|
only for the duration of a calculation.
|
|
</p>
|
|
|
|
<p class="commentary">A last little wrinkle is: how we should scale this? For results like an
|
|
acceleration, something defined in the source text, we know how accurate the
|
|
author wants us to be. But these intermediate kinds are not defined, and we
|
|
don't know for sure what the author would want. It seems wise to set
|
|
\(k \geq k_X\) and \(k\geq k_Y\), so that we have at least as much detail as
|
|
the calculation would have had within each operand kind. So perhaps we should
|
|
put \(k = {\rm max}(k_X, k_Y)\). But in fact we will choose \(k\) = <span class="extract"><span class="extract-syntax">Kinds::Dimensions::lcm(k_X, k_Y)</span></span>,
|
|
the least common multiple, so that any subsequent divisions will cancel
|
|
correctly and we won't lose too much information through integer rounding.
|
|
(In practice this will probably either be the same as \({\rm max}(k_X, k_Y)\)
|
|
or will multiply by 6, since <span class="extract"><span class="extract-syntax">Kinds::Dimensions::lcm(60, 1000) == 6000</span></span> and so on.)
|
|
</p>
|
|
|
|
<p class="commentary">The same unit sequence can have different scalings each time it appears as
|
|
an intermediate calculation. We could get to \({\rm m}^2\cdot {\rm kg}\)
|
|
either as \({\rm m}\cdot{\rm kg}\) times \({\rm m}\), or as \({\rm m^2}\) times
|
|
\({\rm kg}\), or many other ways, and we'll get different scalings depending
|
|
on the route. This is why the <span class="extract"><span class="extract-syntax">unit_sequence</span></span> structure has a
|
|
<span class="extract"><span class="extract-syntax">scaling_factor</span></span> field; the choice of scale factor does not depend on
|
|
the physics but on the arithmetic method being used.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">And otherwise create a kind as the intermediate result of a calculation</span><span class="named-paragraph-number">39.4</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">result</span><span class="plain-syntax">.</span><span class="identifier-syntax">scaling_factor</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP20" class="function-link"><span class="function-syntax">Kinds::Dimensions::lcm</span></a><span class="plain-syntax">(</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">), </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</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-knd.html#SP3_1" class="function-link"><span class="function-syntax">Kinds::intermediate_construction</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP39">§39</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP40"></a><b>§40. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">Kinds::Dimensions::to_rational_power</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">n</span><span class="plain-syntax"> < </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">m</span><span class="plain-syntax"> < </span><span class="constant-syntax">1</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad rational power"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_number</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">op</span><span class="plain-syntax"> = </span><span class="constant-syntax">TIMES_OPERATION</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">n</span><span class="plain-syntax"> < </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">n</span><span class="plain-syntax">; </span><span class="identifier-syntax">op</span><span class="plain-syntax"> = </span><span class="constant-syntax">DIVIDE_OPERATION</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">n</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">K</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</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">n</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">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">K</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">operand</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><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">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP24" class="function-link"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">, </span><span class="identifier-syntax">m</span><span class="plain-syntax">, &</span><span class="identifier-syntax">result</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_3" class="named-paragraph-link"><span class="named-paragraph">Identify the result as a known kind, if possible</span><span class="named-paragraph-number">39.3</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">NULL</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-dk.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-km.html">1</a></li><li class="progresschapter"><a href="2-knd.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresscurrent">dmn</li><li class="progresssection"><a href="3-fv.html">fv</a></li><li class="progresssection"><a href="3-sav.html">sav</a></li><li class="progresschapter"><a href="4-kf.html">4</a></li><li class="progressnext"><a href="3-fv.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|