![]() |
Home | Libraries | People | FAQ | More |
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:
當轉換是不安全的時候,有以下幾各種情況:
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_overflow 和 positive_overflow
).
The following example performs some typical conversions
between numeric types:
以下例子執行了一些數字類型間的典型轉換:
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;
}