[pkg-boost-devel] Bug#844495: boost: multiprecision acos() sometimes does not return (also Bug#844490: FTBFS with boost1.62)

Thibaut Paumard thibaut at debian.org
Fri Nov 25 16:12:14 UTC 2016


Control: tag -1 +patch

Dear all,

I think I've nailed it, see attached patch.

What happens is that when the argument 'b' of acos(b) is the output of
cos(), there exist an exact solution to the equation
 cos(x) == b.

Boost.multiprecision actually tries to resolve this equation
numerically. It estimates somehow the distance between the solution 'x'
and a the current estimate.

In our case, this distance at some point is 0. To check this case, the
implementation actually compares ilogb(b) to FP_ILOGB0:
 http://en.cppreference.com/w/cpp/numeric/math/ilogb
but for some reason, if b of a multiprecision type and is 0, ilogb(b) is
0, not FP_ILOGB0. This, in itself, is probably a bug, that I have not
tried to fix.

Any chance to see this fix or a better one applied in time for stretch?

Regards, Thibaut.



Le 25/11/2016 à 12:44, Thibaut Paumard a écrit :
> Dear all,
> 
> I was able to construct a minimal example, just needed to find a
> specific value to trigger the bug:
> 
> 8<--------------8<------------8<
> 
> #include <boost/multiprecision/cpp_dec_float.hpp>
> 
> int main(int argc, char** argv) {
> 
>   boost::multiprecision::cpp_dec_float_100 alpha100, a, b;
>   alpha100=5.9839860068377014046259e-02;
>   b=cos(alpha100);
>   a=acos(b);
> 
>   return 0;
> }
> 
> 8<--------------8<------------8<
> 
> I compiled that on s390x (sid chroot on zelenka) with g++ (Debian
> 6.2.1-4) 6.2.1 20161119 and the resulting binary never returns.
> 
> The same on jessie (Boost 1.55.0+dfsg-3, g++ (Debian 4.9.2-10) 4.9.2)
> runs through.
> 
> In addition:
> 
> Le 21/11/2016 à 10:02, Thibaut Paumard a écrit :
>>   - this indicates that even more architectures are affected. amd64
>> and i386 seem not to be. The complete list of architectures on which I
>> have been able to trigger the problem is: arm64 armel armhf mips64el
>> ppc64el s390x powerpc ppc64.
> 
> mipsel too.
> 
> However the specific values that trigger the bug may be different on the
> various architectures and seem to depend on the number of digits.
> 
> Regards, Thibaut.
> 

-------------- next part --------------
Description: fix infinite loop in Boost.multiprecision
 Multiprecision acos(), asin() and atan() sometimes loop infinitely when
 they should converge exactly because of the way the distance between the
 current and target value is compared to zero.
Author: Thibaut Paumard <thibaut at debian.org>
Origin: vendor
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=844495
Forwarded: no
Last-Update: 2016-11-25
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
Index: boost1.62-1.62.0+dfsg/boost/multiprecision/detail/functions/trig.hpp
===================================================================
--- boost1.62-1.62.0+dfsg.orig/boost/multiprecision/detail/functions/trig.hpp
+++ boost1.62-1.62.0+dfsg/boost/multiprecision/detail/functions/trig.hpp
@@ -515,10 +515,8 @@ void eval_asin(T& result, const T& x)
       eval_divide(sine, cosine);
       eval_subtract(result, sine);
       current_precision = eval_ilogb(sine);
-#ifdef FP_ILOGB0
-      if(current_precision == FP_ILOGB0)
+      if(sine.iszero())
          break;
-#endif
    }
    if(b_neg)
       result.negate();
@@ -662,10 +660,8 @@ void eval_atan(T& result, const T& x)
       eval_multiply(s, t, c);
       eval_add(result, s);
       current_precision = eval_ilogb(s);
-#ifdef FP_ILOGB0
-      if(current_precision == FP_ILOGB0)
+      if(s.iszero())
          break;
-#endif
    }
    if(b_neg)
       result.negate();


More information about the pkg-boost-devel mailing list