C++ Boost

Boost Numeric Conversion Library

Header boost/numeric/conversion/cast.hpp


Contents


Introduction

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.

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.

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

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, positive_overflow and negative_overflow).


Examples

The following example performs some typical conversions between numeric types:

#include <boost/numeric/conversion/cast.hpp>
#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
      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.
     
     unsigned char c=numeric_cast<unsigned char>(l);
   }
   catch(positive_overflow& e) {
      std::cout << e.what();
   }


   return 0;
}




Back to Numeric Conversion library index


Revised 20 May 2006

© Copyright Boost 1999

© Copyright Fernando Luis Cacciola Carballal, 1999,2004

Use, modification, and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)