| 1 | <HTML> |
|---|
| 2 | <HEAD> |
|---|
| 3 | <LINK REL="stylesheet" TYPE="text/css" HREF="../../../../boost.css"> |
|---|
| 4 | <TITLE>Boost Numeric Conversion Library - numeric_cast</TITLE> |
|---|
| 5 | </HEAD> |
|---|
| 6 | <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> |
|---|
| 7 | <TABLE BORDER="0" CELLPADDING="7" CELLSPACING="0" WIDTH="100%" |
|---|
| 8 | SUMMARY="header"> |
|---|
| 9 | <TR> |
|---|
| 10 | <TH VALIGN="top" WIDTH="300"> |
|---|
| 11 | <H3><A HREF="../../../../index.htm"><IMG HEIGHT="86" WIDTH="277" |
|---|
| 12 | ALT="C++ Boost" SRC="../../../../boost.png" BORDER="0"></A></H3> </TH> |
|---|
| 13 | <TH VALIGN="top"> |
|---|
| 14 | <H1 ALIGN="center">Boost Numeric Conversion Library</H1> |
|---|
| 15 | <H1><A HREF="http://www.boost.org">Header </A><A |
|---|
| 16 | HREF="../../../../boost/numeric/conversion/cast.hpp">boost/numeric/conversion/cast.hpp</A></H1> </TH> |
|---|
| 17 | </TR> |
|---|
| 18 | </TABLE><HR> |
|---|
| 19 | <H2>Contents</H2> |
|---|
| 20 | <UL> |
|---|
| 21 | <LI><A HREF="#introduction">Introduction</A></LI> |
|---|
| 22 | <LI><A HREF="#numeric_cast"><CODE>numeric_cast</CODE></A></LI> |
|---|
| 23 | <LI><A HREF="#examples">Examples</A></LI> |
|---|
| 24 | </UL> <HR> |
|---|
| 25 | <H2><A NAME="introduction">Introduction</A></H2> |
|---|
| 26 | <P>The lack of preservation of range makes conversions between numeric |
|---|
| 27 | types error prone. This is true for both implicit conversions and explicit |
|---|
| 28 | conversions (through static_cast). <A HREF="#numeric_cast"> numeric_cast</A> |
|---|
| 29 | detects loss of range when a numeric type is converted, and throws an |
|---|
| 30 | exception if the range cannot be preserved.</P> |
|---|
| 31 | <P>There are several situations where conversions are unsafe: </P> |
|---|
| 32 | <UL> |
|---|
| 33 | <LI>Conversions from an integral type with a wider range than the target |
|---|
| 34 | integral type.</LI> |
|---|
| 35 | <LI> Conversions from unsigned to signed (and vice versa) integral |
|---|
| 36 | types.</LI> |
|---|
| 37 | <LI> Conversions from floating point types to integral types.</LI> |
|---|
| 38 | </UL> |
|---|
| 39 | <P>The C++ Standard does not specify the behavior when a numeric type is |
|---|
| 40 | assigned a value that cannot be represented by the type, except for unsigned |
|---|
| 41 | integral types [3.9.1.4], which must obey the laws of arithmetic modulo |
|---|
| 42 | 2<SUP>n</SUP> (this implies that the result will be reduced modulo the number |
|---|
| 43 | that is one greater than the largest value that can be represented). The fact |
|---|
| 44 | that the behavior for overflow is undefined for all conversions (except the |
|---|
| 45 | aforementioned unsigned to unsigned) makes any code that may produce positive |
|---|
| 46 | or negative overflows exposed to portability issues.</P> |
|---|
| 47 | <P>numeric_cast adheres to the rules for implicit conversions mandated by |
|---|
| 48 | the C++ Standard, such as truncating floating point types when converting to |
|---|
| 49 | integral types. The implementation must guarantee that for a conversion to a |
|---|
| 50 | type that can hold all possible values of the source type, there will be no |
|---|
| 51 | runtime overhead. <BR> <BR> </P> <HR> |
|---|
| 52 | <H2><A NAME="numeric_cast"><CODE>numeric_cast</CODE></A></H2> |
|---|
| 53 | <BLOCKQUOTE> |
|---|
| 54 | <PRE>template<typename Target, typename Source> inline |
|---|
| 55 | typename boost::numeric::converter<Target,Source>::result_type |
|---|
| 56 | numeric_cast ( Source arg ) |
|---|
| 57 | { |
|---|
| 58 | return boost::numeric::converter<Target,Source>::convert(arg); |
|---|
| 59 | } |
|---|
| 60 | </PRE> </BLOCKQUOTE> |
|---|
| 61 | <P>numeric_cast returns the result of converting a value of type Source to a value of type |
|---|
| 62 | Target. If out-of-range is detected, an exception is thrown (see |
|---|
| 63 | <A HREF="converter_policies.html#bad_numc">bad_numeric_cast</A>, <A |
|---|
| 64 | HREF="converter_policies.html#posovr">positive_overflow</A> and |
|---|
| 65 | <A HREF="converter_policies.html#negovr">negative_overflow</A>). <BR> <BR> </P> <HR> |
|---|
| 66 | <H2><A NAME="examples">Examples</A></H2> |
|---|
| 67 | <P>The following example performs some typical conversions between numeric |
|---|
| 68 | types: </P> |
|---|
| 69 | <BLOCKQUOTE> |
|---|
| 70 | <PRE>#include <boost/numeric/conversion/cast.hpp> |
|---|
| 71 | #include <iostream> |
|---|
| 72 | |
|---|
| 73 | int main() |
|---|
| 74 | { |
|---|
| 75 | using boost::numeric_cast; |
|---|
| 76 | |
|---|
| 77 | using boost::numeric::bad_numeric_cast; |
|---|
| 78 | using boost::numeric::positive_overflow; |
|---|
| 79 | using boost::numeric::negative_overflow; |
|---|
| 80 | |
|---|
| 81 | try |
|---|
| 82 | { |
|---|
| 83 | int i=42; |
|---|
| 84 | short s=numeric_cast<short>(i); // This conversion succeeds (is in range) |
|---|
| 85 | } |
|---|
| 86 | catch(negative_overflow& e) { |
|---|
| 87 | std::cout << e.what(); |
|---|
| 88 | } |
|---|
| 89 | catch(positive_overflow& e) { |
|---|
| 90 | std::cout << e.what(); |
|---|
| 91 | } |
|---|
| 92 | |
|---|
| 93 | try |
|---|
| 94 | { |
|---|
| 95 | float f=-42.1234; |
|---|
| 96 | |
|---|
| 97 | // This will cause a boost::numeric::negative_overflow exception to be thrown |
|---|
| 98 | unsigned int i=numeric_cast<unsigned int>(f); |
|---|
| 99 | } |
|---|
| 100 | catch(bad_numeric_cast& e) { |
|---|
| 101 | std::cout << e.what(); |
|---|
| 102 | } |
|---|
| 103 | |
|---|
| 104 | double d= f + numeric_cast<double>(123); // int -> double |
|---|
| 105 | |
|---|
| 106 | unsigned long l=std::numeric_limits<unsigned long>::max(); |
|---|
| 107 | |
|---|
| 108 | try |
|---|
| 109 | { |
|---|
| 110 | // This will cause a boost::numeric::positive_overflow exception to be thrown |
|---|
| 111 | // NOTE: *operations* on unsigned integral types cannot cause overflow |
|---|
| 112 | // but *conversions* to a signed type ARE range checked by numeric_cast. |
|---|
| 113 | |
|---|
| 114 | unsigned char c=numeric_cast<unsigned char>(l); |
|---|
| 115 | } |
|---|
| 116 | catch(positive_overflow& e) { |
|---|
| 117 | std::cout << e.what(); |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | |
|---|
| 121 | return 0; |
|---|
| 122 | }</PRE> </BLOCKQUOTE> <BR> <BR> <HR> |
|---|
| 123 | <HR> |
|---|
| 124 | <P>Back to <A HREF="index.html">Numeric Conversion library index</A></P> |
|---|
| 125 | <HR> |
|---|
| 126 | <P>Revised 20 May 2006</P> |
|---|
| 127 | <p>© Copyright Boost 1999</p> |
|---|
| 128 | <p>© Copyright Fernando Luis Cacciola Carballal, 1999,2004</p> |
|---|
| 129 | <p> Use, modification, and distribution are subject to the Boost Software |
|---|
| 130 | License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> |
|---|
| 131 | LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> |
|---|
| 132 | www.boost.org/LICENSE_1_0.txt</a>)</p> |
|---|
| 133 | </BODY> |
|---|
| 134 | </HTML> |
|---|