Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Units 單位

Base Units 基礎單位
Scaled Base Units 成比例基礎單位
Scaled Units 成比例單位

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等函數的正確的重載。 這些操作通過自由函數powroot提供, 這些函數都是基於整數和靜態有理數(static_rational)的模板, 並可以工具類power_typeof_helperroot_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_unitsecond_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.
這種做法有幾種好處。

  • It reflects the real meaning of these units better than treating them as independent units.
    它比孤立地處理單位要好,這樣可以反應出這些單位的真實意義。
  • 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.
    如果克(gram)或者千克(kilogram)有一個與別的單位有轉換關係,那麼它會自動應用到克(gram)和千克(kilogram)兩個上,只需要一個特化而已。
  • Similarly, if the symbol for grams is defined as "g", then the symbol for kilograms will be "kg" without any extra effort.
    類似地,如果克(gram)的符號(symbol)是"g",那麼千克(kilogram)的符號(symbol)就會自動被定義為"kg"。

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

PrevUpHomeNext