summaryrefslogtreecommitdiff
path: root/doc/html/boost_units/Units.html
blob: d4478777980cfe679aa3d1b34627a57f515c20a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Units</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../boost_units.html" title="Chapter&#160;37.&#160;Boost.Units 1.1.0">
<link rel="prev" href="Dimensional_Analysis.html" title="Dimensional Analysis">
<link rel="next" href="Quantities.html" title="Quantities">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="Dimensional_Analysis.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_units.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="Quantities.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_units.Units"></a><a class="link" href="Units.html" title="Units">Units</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="Units.html#boost_units.Units.base_units">Base Units</a></span></dt>
<dt><span class="section"><a href="Units.html#boost_units.Units.scaled_base_units">Scaled Base Units</a></span></dt>
<dt><span class="section"><a href="Units.html#boost_units.Units.scaled_units">Scaled Units</a></span></dt>
</dl></div>
<p>
      We define a <span class="bold"><strong>unit</strong></span> as a set of base units each
      of which can be raised to an arbitrary rational exponent. Thus, the SI unit
      corresponding to the dimension of force is kg m s^-2, where kg, m, and s are
      base units. We use the notion of a <span class="bold"><strong>unit system</strong></span>
      such as SI to specify the mapping from a dimension to a particular unit so
      that instead of specifying the base units explicitly, we can just ask for the
      representation of a dimension in a particular system.
    </p>
<p>
      Units are, like dimensions, purely compile-time variables with no associated
      value. Units obey the same algebra as dimensions do; the presence of the unit
      system serves to ensure that units having identical reduced dimension in different
      systems (like feet and meters) cannot be inadvertently mixed in computations.
    </p>
<p>
      There are two distinct types of systems that can be envisioned:
    </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
          <span class="bold"><strong>Homogeneous systems</strong></span> : Systems which hold
          a linearly independent set of base units which can be used to represent
          many different dimensions. For example, the SI system has seven base dimensions
          and seven base units corresponding to them. It can represent any unit which
          uses only those seven base dimensions. Thus it is a homogeneous_system.
        </li>
<li class="listitem">
          <span class="bold"><strong>Heterogeneous systems</strong></span> : Systems which
          store the exponents of every base unit involved are termed heterogeneous.
          Some units can only be represented in this way. For example, area in m
          ft is intrinsically heterogeneous, because the base units of meters and
          feet have identical dimensions. As a result, simply storing a dimension
          and a set of base units does not yield a unique solution. A practical example
          of the need for heterogeneous units, is an empirical equation used in aviation:
          H = (r/C)^2 where H is the radar beam height in feet and r is the radar
          range in nautical miles. In order to enforce dimensional correctness of
          this equation, the constant, C, must be expressed in nautical miles per
          foot^(1/2), mixing two distinct base units of length.
        </li>
</ul></div>
<p>
      Units are implemented by the <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span>
      template class defined in <code class="computeroutput"><a class="link" href="Reference.html#header.boost.units.unit_hpp" title="Header &lt;boost/units/unit.hpp&gt;">boost/units/unit.hpp</a></code>
      :
    </p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Dim</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">System</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">unit</span><span class="special">;</span>
</pre>
<p>
      In addition to supporting the compile-time dimensional analysis operations,
      the +, -, *, and / runtime operators are provided for <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span> variables. Because the
      dimension associated with powers and roots must be computed at compile-time,
      it is not possible to provide overloads for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pow</span></code> that
      function correctly for <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span>s.
      These operations are supported through free functions <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/pow_idm45506852379376.html" title="Function template pow">pow</a></code></span> and <span class="underline"><code class="computeroutput"><a class="link" href="Reference.html#boost.units.root_idm45506851526112">root</a></code></span> that are templated
      on integer and <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/static_rational.html" title="Class template static_rational">static_rational</a></code></span>
      values and can take as an argument any type for which the utility classes
      <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/power_typeof_helper.html" title="Struct template power_typeof_helper">power_typeof_helper</a></code></span>
      and <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/root_typeof_helper.html" title="Struct template root_typeof_helper">root_typeof_helper</a></code></span>
      have been defined.
    </p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_units.Units.base_units"></a><a class="link" href="Units.html#boost_units.Units.base_units" title="Base Units">Base Units</a>
</h3></div></div></div>
<p>
        Base units are defined much like base dimensions.
      </p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Derived</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Dimensions</span><span class="special">,</span> <span class="keyword">long</span> <span class="identifier">N</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">base_unit</span> <span class="special">{</span> <span class="special">...</span> <span class="special">};</span>
</pre>
<p>
        Again negative ordinals are reserved.
      </p>
<p>
        As an example, in the following we will implement a subset of the SI unit
        system based on the fundamental dimensions given above, demonstrating all
        steps necessary for a completely functional system. First, we simply define
        a unit system that includes type definitions for commonly used units:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">meter_base_unit</span> <span class="special">:</span> <span class="identifier">base_unit</span><span class="special">&lt;</span><span class="identifier">meter_base_unit</span><span class="special">,</span> <span class="identifier">length_dimension</span><span class="special">,</span> <span class="number">1</span><span class="special">&gt;</span> <span class="special">{</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">kilogram_base_unit</span> <span class="special">:</span> <span class="identifier">base_unit</span><span class="special">&lt;</span><span class="identifier">kilogram_base_unit</span><span class="special">,</span> <span class="identifier">mass_dimension</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span> <span class="special">{</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">second_base_unit</span> <span class="special">:</span> <span class="identifier">base_unit</span><span class="special">&lt;</span><span class="identifier">second_base_unit</span><span class="special">,</span> <span class="identifier">time_dimension</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;</span> <span class="special">{</span> <span class="special">};</span>

<span class="keyword">typedef</span> <span class="identifier">make_system</span><span class="special">&lt;</span>
    <span class="identifier">meter_base_unit</span><span class="special">,</span>
    <span class="identifier">kilogram_base_unit</span><span class="special">,</span>
    <span class="identifier">second_base_unit</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">mks_system</span><span class="special">;</span>

<span class="comment">/// unit typedefs</span>
<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">dimensionless_type</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span>      <span class="identifier">dimensionless</span><span class="special">;</span>

<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">length_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span>        <span class="identifier">length</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">mass_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span>          <span class="identifier">mass</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">time_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span>          <span class="identifier">time</span><span class="special">;</span>

<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">area_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span>          <span class="identifier">area</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">energy_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span>        <span class="identifier">energy</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
        The macro <span class="underline"><code class="computeroutput"><a class="link" href="../BOOST_UNITS_STATIC_CONSTANT.html" title="Macro BOOST_UNITS_STATIC_CONSTANT">BOOST_UNITS_STATIC_CONSTANT</a></code></span>
        is provided in <code class="computeroutput"><a class="link" href="Reference.html#header.boost.units.static_constant_hpp" title="Header &lt;boost/units/static_constant.hpp&gt;">boost/units/static_constant.hpp</a></code>
        to facilitate ODR- and thread-safe constant definition in header files. We
        then define some constants for the supported units to simplify variable definitions:
      </p>
<p>
</p>
<pre class="programlisting"><span class="comment">/// unit constants </span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">meter</span><span class="special">,</span><span class="identifier">length</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">meters</span><span class="special">,</span><span class="identifier">length</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">kilogram</span><span class="special">,</span><span class="identifier">mass</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">kilograms</span><span class="special">,</span><span class="identifier">mass</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">second</span><span class="special">,</span><span class="identifier">time</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">seconds</span><span class="special">,</span><span class="identifier">time</span><span class="special">);</span>

<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">square_meter</span><span class="special">,</span><span class="identifier">area</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">square_meters</span><span class="special">,</span><span class="identifier">area</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">joule</span><span class="special">,</span><span class="identifier">energy</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">joules</span><span class="special">,</span><span class="identifier">energy</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        If support for textual output of units is desired, we can also specialize
        the <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/base_unit_info.html" title="Struct template base_unit_info">base_unit_info</a></code></span>
        class for each fundamental dimension tag:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> <span class="identifier">base_unit_info</span><span class="special">&lt;</span><span class="identifier">test</span><span class="special">::</span><span class="identifier">meter_base_unit</span><span class="special">&gt;</span>
<span class="special">{</span>
    <span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">()</span>               <span class="special">{</span> <span class="keyword">return</span> <span class="string">"meter"</span><span class="special">;</span> <span class="special">}</span>
    <span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">symbol</span><span class="special">()</span>             <span class="special">{</span> <span class="keyword">return</span> <span class="string">"m"</span><span class="special">;</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        and similarly for <code class="computeroutput"><span class="identifier">kilogram_base_unit</span></code>
        and <code class="computeroutput"><span class="identifier">second_base_unit</span></code>. A future
        version of the library will provide a more flexible system allowing for internationalization
        through a facet/locale-type mechanism. The <code class="computeroutput"><span class="identifier">name</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">symbol</span><span class="special">()</span></code> methods of <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/base_unit_info.html" title="Struct template base_unit_info">base_unit_info</a></code></span>
        provide full and short names for the base unit. With these definitions, we
        have the rudimentary beginnings of our unit system, which can be used to
        determine reduced dimensions for arbitrary unit calculations.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_units.Units.scaled_base_units"></a><a class="link" href="Units.html#boost_units.Units.scaled_base_units" title="Scaled Base Units">Scaled Base Units</a>
</h3></div></div></div>
<p>
        Now, it is also possible to define a base unit as being a multiple of another
        base unit. For example, the way that <code class="computeroutput"><span class="identifier">kilogram_base_unit</span></code>
        is actually defined by the library is along the following lines
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">gram_base_unit</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">units</span><span class="special">::</span><span class="identifier">base_unit</span><span class="special">&lt;</span><span class="identifier">gram_base_unit</span><span class="special">,</span> <span class="identifier">mass_dimension</span><span class="special">,</span> <span class="number">1</span><span class="special">&gt;</span> <span class="special">{};</span>
<span class="keyword">typedef</span> <span class="identifier">scaled_base_unit</span><span class="special">&lt;</span><span class="identifier">gram_base_unit</span><span class="special">,</span> <span class="identifier">scale</span><span class="special">&lt;</span><span class="number">10</span><span class="special">,</span> <span class="identifier">static_rational</span><span class="special">&lt;</span><span class="number">3</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">kilogram_base_unit</span><span class="special">;</span>
</pre>
<p>
        This basically defines a kilogram as being 10^3 times a gram.
      </p>
<p>
        There are several advantages to this approach.
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            It reflects the real meaning of these units better than treating them
            as independent units.
          </li>
<li class="listitem">
            If a conversion is defined between grams or kilograms and some other
            units, it will automatically work for both kilograms and grams, with
            only one specialization.
          </li>
<li class="listitem">
            Similarly, if the symbol for grams is defined as "g", then
            the symbol for kilograms will be "kg" without any extra effort.
          </li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_units.Units.scaled_units"></a><a class="link" href="Units.html#boost_units.Units.scaled_units" title="Scaled Units">Scaled Units</a>
</h3></div></div></div>
<p>
        We can also scale a <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span>
        as a whole, rather than scaling the individual base units which comprise
        it. For this purpose, we use the metafunction <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/make_scaled_unit.html" title="Struct template make_scaled_unit">make_scaled_unit</a></code></span>.
        The main motivation for this feature is the metric prefixes defined in <code class="computeroutput"><a class="link" href="Reference.html#header.boost.units.systems.si.prefixes_hpp" title="Header &lt;boost/units/systems/si/prefixes.hpp&gt;">boost/units/systems/si/prefixes.hpp</a></code>.
      </p>
<p>
        A simple example of its usage would be.
      </p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">make_scaled_unit</span><span class="special">&lt;</span><span class="identifier">si</span><span class="special">::</span><span class="identifier">time</span><span class="special">,</span> <span class="identifier">scale</span><span class="special">&lt;</span><span class="number">10</span><span class="special">,</span> <span class="identifier">static_rational</span><span class="special">&lt;-</span><span class="number">9</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">nanosecond</span><span class="special">;</span>
</pre>
<p>
        nanosecond is a specialization of <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span>,
        and can be used in a quantity normally.
      </p>
<pre class="programlisting"><span class="identifier">quantity</span><span class="special">&lt;</span><span class="identifier">nanosecond</span><span class="special">&gt;</span> <span class="identifier">t</span><span class="special">(</span><span class="number">1.0</span> <span class="special">*</span> <span class="identifier">si</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">t</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>    <span class="comment">// prints 1e9 ns</span>
</pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2003-2008 Matthias Christian Schabel<br>Copyright &#169; 2007-2010 Steven
      Watanabe<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="Dimensional_Analysis.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_units.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="Quantities.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>