Skip to content

boost::numeric::interval неправильно работает под MSVC 2015 x64 #36

@PolarNick239

Description

@PolarNick239

Привет! :)

Видимо эту строку

typedef boost::numeric::interval_lib::unprotect<boost::numeric::interval<double> >::type interval;
надо заменить на что-то вроде этого:

#if defined(_MSC_VER) && (defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP > 0)))
         // This is because MSVC compiler (2015) has SSE enabled by default for x64, and thus rounding mode can't be saved and should be specified each time
         // See also:
         // https://www.gecode.org/users-archive/2016-May/004862.html
         // https://github.com/Gecode/gecode/blob/7390b0b16bd7cc0cc385f3e8fd9436ca9897d065/gecode/float.hh#L131-L147
         typedef boost::numeric::interval_lib::save_state<boost::numeric::interval_lib::rounded_arith_std<T>> RoundingBase;
#else
         // Faster version thanks to saving rounding mode in state, also surprisingly rounded_arith_std leads to failed tests on GCC 5.4.0
         typedef boost::numeric::interval_lib::rounded_arith_opp<T> RoundingBase;
#endif
         typedef boost::numeric::interval_lib::checking_strict<T> CheckingBase;
         typedef boost::numeric::interval<double, boost::numeric::interval_lib::policies<RoundingBase, CheckingBase>> interval;

т.к. MSVC 2015 под x64 по умолчанию использует SSE2 (выдержка из https://www.gecode.org/users-archive/2016-May/004862.html):

if you look at the documentation
homepage, you'll see a big red warning :)

http://www.boost.org/doc/libs/1_61_0/libs/numeric/interval/doc/interval.htm

which says that the library probably won't work with SSE2 (or at least not
out of the box). But SSE2 is the only option for x64.

On the other hand, I'm not aware of any good alternative to this Boost
library. I think the library is actually quite good (even though it would
use some work on supporting SSE2 better).

So I thought I'd play with the library's policies to see if I could make it
work with x64. I looked into float.hh which defines what exact interval
datatype is used. It looks like changing from 'rounded_arith_opp' to
'rounded_arith_std' fixes the issues that we're observing. If you're
interested the description of those types is available here:

http://www.boost.org/doc/libs/1_61_0/libs/numeric/interval/doc/rounding.htm

Отправил бы PR, но не уверен что ничего не упускаю, т.к. не понимаю две вещи:

  1. Почему раньше использовался typedef interval_lib::unprotect<...>::type interval;
  2. Почему под GCC 5.4.0 rounded_arith_std дает не верный результат

P.S. см.:
https://www.gecode.org/users-archive/2016-May/004862.html
https://github.com/Gecode/gecode/blob/7390b0b16bd7cc0cc385f3e8fd9436ca9897d065/gecode/float.hh#L131-L147

P.P.S. понимаю что репозиторий не обновляется, но на всякий случай пусть будет хотя бы Issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions