![]() |
Home | Libraries | People | FAQ | More |
We define a unit as a linear combination of
base units. 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 unit system 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.
我們把基礎單位(base unit)的線性組合(linear combination)定義為單位(unit)。
例如,SI中力(force)的單位(unit)是kg m s^-2,其中kg、m、s都是基礎單位(base unit)。
我們使用單位系統(unit system)(如SI)來表明從量綱(dimension)到具體單位(particular unit)的映射,這樣就不必總是明確指明基礎單位(base unit),只是說明某個特定系統(particular system)下的量綱(dimension)就可以了。
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.
單位(unit)和量綱(dimension)一樣,都是純粹的編譯時變量,並沒有相關的值。
單位(unit)同樣遵循量綱(dimension)的代數(algebra)法則;單位系統(unit system)保證
在不同系統中可以化簡為相同reduced dimension的單位(例如英尺(feet)和米(meter))並不會被無意中混雜在一起。
There are two distinct types of systems that can be envisioned:
在想像中有兩種不同類型的系統:
Units are implemented by the unit
template class defined in boost/units/unit.hpp
:
單位由定義在boost/units/unit.hpp文件中的模板類unit實現:
template<class Dim,class System> class unit;
In addition to supporting the compile-time dimensional analysis operations,
the +, -, *, and / runtime operators are provided for unit variables. Because the
dimension associated with powers and roots must be computed at compile-time,
it is not possible to provide overloads for std::pow that
function correctly for units.
These operations are supported through free functions pow and root that are templated
on integer and static_rational
values and can take as an argument any type for which the utility classes
power_typeof_helper
and root_typeof_helper
have been defined.
為了支持編譯時量綱分析(compile-time dimensional analysis),+、-、*、/等運行時操作符由unit變量提供。
因為乘方(power)和開方(root)的量綱(dimension)必須在編譯時計算,所以不太可能為unit提供std::pow等函數的正確的重載。
這些操作通過自由函數pow和root提供,
這些函數都是基於整數和靜態有理數(static_rational)的模板,
並可以工具類power_typeof_helper和root_typeof_helper定義的任意類型為參數。
Base units are defined much like base dimensions.
基礎單位(base unit)定義類似於基礎量綱(base dimension)。
template<class Derived, class Dimensions, long N> struct base_unit { ... };
Again negative ordinals are reserved.
負數的序號再次被保留。
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:
舉個例子,下面我們將根據之前定義的基本量綱(fundamental dimension)實現一SI單位系統(SI unit system)的一部分,
展示定義一個完整系統所必須的步驟。首先,我們簡單地定義一個單位系統(unit system)包含常見單位的類型定義(type definition):
struct meter_base_unit : base_unit<meter_base_unit, length_dimension, 1> { }; struct kilogram_base_unit : base_unit<kilogram_base_unit, mass_dimension, 2> { }; struct second_base_unit : base_unit<second_base_unit, time_dimension, 3> { }; typedef make_system< meter_base_unit, kilogram_base_unit, second_base_unit>::type mks_system; /// unit typedefs typedef unit<dimensionless_type,mks_system> dimensionless; typedef unit<length_dimension,mks_system> length; typedef unit<mass_dimension,mks_system> mass; typedef unit<time_dimension,mks_system> time; typedef unit<area_dimension,mks_system> area; typedef unit<energy_dimension,mks_system> energy;
The macro BOOST_UNITS_STATIC_CONSTANT
is provided in boost/units/static_constant.hpp
to facilitate ODR- and thread-safe constant definition in header files. We
then define some constants for the supported units to simplify variable definitions:
宏BOOST_UNITS_STATIC_CONSTANT定義於boost/units/static_constant.hpp頭文件中,以方便地在頭文件中實現ODR-(One Definition Rule 一次定義法則)和線程安全(thread-safe)的常量(constant)定義。
我們接下來定義幾個支持單位的常量來簡化變量定義:
/// unit constants BOOST_UNITS_STATIC_CONSTANT(meter,length); BOOST_UNITS_STATIC_CONSTANT(meters,length); BOOST_UNITS_STATIC_CONSTANT(kilogram,mass); BOOST_UNITS_STATIC_CONSTANT(kilograms,mass); BOOST_UNITS_STATIC_CONSTANT(second,time); BOOST_UNITS_STATIC_CONSTANT(seconds,time); BOOST_UNITS_STATIC_CONSTANT(square_meter,area); BOOST_UNITS_STATIC_CONSTANT(square_meters,area); BOOST_UNITS_STATIC_CONSTANT(joule,energy); BOOST_UNITS_STATIC_CONSTANT(joules,energy);
If support for textual output of units is desired, we can also specialize
the base_unit_info
class for each fundamental dimension tag:
如果支持單位(unit)的文本輸出(textual output),我們需要為每個基本量綱標籤(fundamental dimension tag)特化(specialize)base_unit_info類:
template<> struct base_unit_info<test::meter_base_unit> { static std::string name() { return "meter"; } static std::string symbol() { return "m"; } };
and similarly for kilogram_base_unit
and second_base_unit. A future
version of the library will provide a more flexible system allowing for internationalization
through a facet/locale-type mechanism. The name() and symbol() methods of base_unit_info
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.
kilogram_base_unit和second_base_unit也是同樣。
未來的版本會通過facet/locale-type機制提供一個支持國際化(internationalization)的可伸縮(flexible)系統。
base_unit_info類的name()和symbol()方法提供了基礎單位(base unit)的全稱和簡稱。
通過這些定義,我們有了單位系統(unit system)最基本的開始,能夠為任意的單位運算提供reduced dimension。
Now, it is also possible to define a base unit as being a multiple of another
base unit. For example, the way that kilogram_base_unit
is actually defined by the library is along the following lines
現在,我們有可能定義一個基礎單位是另一個基礎單位的倍數。例如,kilogram_base_unit在庫中就是下面這樣定義的
struct gram_base_unit : boost::units::base_unit<gram_base_unit, mass_dimension, 1> {}; typedef scaled_base_unit<gram_base_unit, scale<10, static_rational<3> > > kilogram_base_unit;
This basically defines a kilogram as being 10^3 times a gram.
這裡定義了千克(kilogram)是克(gram)的1000倍。
There are several advantages to this approach.
這種做法有幾種好處。
We can also scale a unit
as a whole, rather than scaling the individual base units which comprise
it. For this purpose, we use the metafunction make_scaled_unit.
The main motivation for this feature is the metric prefixes defined in boost/units/systems/si/prefixes.hpp.
我們也可以直接為單位(unit)定義比例,而不是為組合的每個基礎單位(base unit)定義比例。
為了這個目的,我們可以使用元函數(metafunction) make_scaled_unit。
這個特點主要的動機是為了定義在boost/units/systems/si/prefixes.hpp文件中的公制前綴(metric prefixes)。
A simple example of its usage would be.
一個用法的簡單例子如下。
typedef make_scaled_unit<si::time, scale<10, static_rational<-9> > >::type nanosecond;
nanosecond is a specialization of unit,
and can be used in a quantity normally.
納秒(nanosecond)是一個特化(specialization)的單位(unit),可以像通常一樣表示數量(quantity)。
quantity<nanosecond> t(1.0 * si::seconds); std::cout << t << std::endl; // prints 1e9 ns