Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Improved numeric_cast<> 改進的 numeric_cast<>

Introduction 簡介
numeric_cast
Examples 例子

The lack of preservation of range makes conversions between numeric types error prone. This is true for both implicit conversions and explicit conversions (through static_cast). numeric_cast detects loss of range when a numeric type is converted, and throws an exception if the range cannot be preserved.
由於缺乏對範圍的保護,所以數字類型間的轉換很容易出錯。這對於隱式轉換和顯式轉換(通過 static_cast) 都是一樣的。numeric_cast 可以在轉換一個數字類型時檢查範圍的損失,如果範圍不能被保持就拋出一個異常。

There are several situations where conversions are unsafe:
當轉換是不安全的時候,有以下幾各種情況:

  • Conversions from an integral type with a wider range than the target integral type.
    從一個比目標類型範圍更寬的整型類型進行轉換。
  • Conversions from unsigned to signed (and vice versa) integral types.
    從無符號整型到有符號整型(以及相反方向)的轉換。
  • Conversions from floating point types to integral types.
    從浮點類型到整型類型的轉換。

The C++ Standard does not specify the behavior when a numeric type is assigned a value that cannot be represented by the type, except for unsigned integral types [3.9.1.4], which must obey the laws of arithmetic modulo 2n (this implies that the result will be reduced modulo the number that is one greater than the largest value that can be represented). The fact that the behavior for overflow is undefined for all conversions (except the aforementioned unsigned to unsigned) makes any code that may produce positive or negative overflows exposed to portability issues.
C+ +標準沒有規定當一個數字類型被賦予一個該類型不能表示的值時的行為,除了無符號整數類型以外[3.9.1.4],後者必須遵守模2n算術的法則(這意味 著結果會將大於可表示的最大值的數進行取模降值)。事實上,對於所有轉換(除了上述的無符號至無符號的轉換),溢出的行為是未定義的,這使得任何可能產生 正或負的溢出的代碼都存在可移植性的問題。

numeric_cast adheres to the rules for implicit conversions mandated by the C++ Standard, such as truncating floating point types when converting to integral types. The implementation must guarantee that for a conversion to a type that can hold all possible values of the source type, there will be no runtime overhead.
numeric_cast 遵守C++標準所制定的隱式轉換規則,例如將浮點類型轉換為整型類型時進行截斷。其實現必須保證對於到一個類型的轉換,可以保持源類型的所有可能值,且沒有運行期開銷。

template<typename Target, typename Source> inline
typename boost::numeric::converter<Target,Source>::result_type
numeric_cast ( Source arg )
{
return boost::numeric::converter<Target,Source>::convert(arg);
}

numeric_cast returns the result of converting a value of type Source to a value of type Target. If out-of-range is detected, an exception is thrown (see bad_numeric_cast, negative_overflow and positive_overflow ).
numeric_cast 返回一個類型為 Source 的值轉換為類型為 Target 的值的結果。如果檢測到超出範圍,將拋出一個異常(請見 bad_numeric_cast, negative_overflowpositive_overflow ).

The following example performs some typical conversions between numeric types:
以下例子執行了一些數字類型間的典型轉換:

  1. include <boost/numeric/conversion/cast.hpp>
  2. include <iostream>
int main()
{
using boost::numeric_cast;
using boost::numeric::bad_numeric_cast;
using boost::numeric::positive_overflow;
using boost::numeric::negative_overflow;
try
{
int i=42;
short s=numeric_cast<short>(i); // This conversion succeeds (is in range) 轉換成功(在範圍內)
}
catch(negative_overflow& e) {
std::cout << e.what();
}
catch(positive_overflow& e) {
std::cout << e.what();
}
try
{
float f=-42.1234;
// This will cause a boost::numeric::negative_overflow exception to be thrown
// 這將引發一個
boost::numeric::negative_overflow 異常被拋出
unsigned int i=numeric_cast<unsigned int>(f);
}
catch(bad_numeric_cast& e) {
std::cout << e.what();
}
double d= f + numeric_cast<double>(123); // int -> double

unsigned long l=std::numeric_limits<unsigned long>::max();
try
{
// This will cause a boost::numeric::positive_overflow exception to be thrown
// NOTE: *operations* on unsigned integral types cannot cause overflow
// but *conversions* to a signed type ARE range checked by numeric_cast.
//
這將引發一個 boost::numeric::positive_overflow 異常被拋出
// 註:在無符號整數類型上的*operations*不會引起溢出,
// 但是
在有符號類型上的*operations*則要由 numeric_cast 進行範圍檢查

unsigned char c=numeric_cast<unsigned char>(l);
}
catch(positive_overflow& e) {
std::cout << e.what();
}
return 0;
}

PrevUpHomeNext