Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Improved numeric_cast<>

Boost , Chapter 1. Boost.NumericConversion , Chapter 1. Boost.NumericConversion

Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Отсутствие сохранения диапазона делает конверсии между числовыми типами склонными к ошибкам. Это верно как для неявных, так и для явных конверсий (черезstatic_cast)..Численностьобнаруживает потерю диапазона при преобразовании числового типа и делает исключение, если диапазон не может быть сохранен.

Существует несколько ситуаций, когда конверсия небезопасна:

  • Конверсии из интегрального типа с более широким диапазоном, чем целевой интегральный тип.
  • Конверсии из неподписанных в подписанные (и наоборот) интегральные типы.
  • Преобразования из типов с плавающей точкой в интегральные типы.

C++ Стандарт не определяет поведение, когда числовому типу присваивается значение, которое не может быть представлено типом, за исключением неподписанных интегральных типов [3.9.1.4], которые должны подчиняться законам арифметического модуля 2n (это подразумевает, что в результате будет уменьшено модульное число, которое на одно больше самого большого значения, которое может быть представлено). Тот факт, что поведение переполнения не определено для всех конверсий (за исключением вышеупомянутых неподписанных), делает любой код, который может привести к положительным или отрицательным переполнениям, подверженным проблемам переносимости.

По умолчаниюnumeric_castпридерживается правил неявных конверсий, санкционированных C++. Стандартные, такие как усечение типов плавающих точек при преобразовании в интегральные типы. Реализация должна гарантировать, что для преобразования в тип, который может содержать все возможные значения типа источника, не будет накладных расходов на время выполнения.

template <typename Target, typename Source> inline
Target numeric_cast( Source arg )
{
    typedef conversion_traits<Target, Source>   conv_traits;
    typedef numeric_cast_traits<Target, Source> cast_traits;
    typedef converter
        <
            Target,
            Source,
            conv_traits,
            typename cast_traits::overflow_policy,
            typename cast_traits::rounding_policy,
            raw_converter<conv_traits>,
            typename cast_traits::range_checking_policy
        > converter;
    return converter::convert(arg);
}

numeric_castвозвращает результат преобразования значения типа Источник в значение типа Цель. При обнаружении вне диапазона выполняется политика переполнения, поведение которой по умолчанию заключается в том, чтобы бросить исключение (см.bad_numeric_cast,negative_overflowиpositive_overflow).

template <typename Target, typename Source, typename EnableIf = void>
struct numeric_cast_traits
{
    typedef def_overflow_handler    overflow_policy;
    typedef UseInternalRangeChecker range_checking_policy;
    typedef Trunc<Source>           rounding_policy;
};

Поведениеnumeric_castможет быть адаптировано для пользовательских числовых типов посредством специализацииnumeric_cast_traits. )

Следующий пример выполняет некоторые типичные преобразования между числовыми типами:

  1. включает
  2. Включает
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;
}

PrevUpHomeNext

Статья Improved numeric_cast<> раздела Chapter 1. Boost.NumericConversion Chapter 1. Boost.NumericConversion может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 1. Boost.NumericConversion ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 20:47:14/0.0069260597229004/0