Opened 8 years ago

Closed 8 years ago

#10993 closed Bugs (fixed)

frexp with multiprecision cpp_dec_float_50 returns random values with VS 2013

Reported by: Paul A. Bristow Owned by: christopher_kormanyos
Milestone: To Be Determined Component: multiprecision
Version: Boost 1.57.0 Severity: Problem
Keywords: cpp_dec_float_50 Cc:

Description

With VS 2013, math function frexp with multiprecision cpp_dec_float_50 and with expression-templates ON returns spectacularly wrong and random values.

GCC 4.9.1 returns the expected values.

Switching expression-templates OFF also works as expected.

multiprecision cpp_bin_float_50 works as expected.

Attachments (1)

test.cpp (1012 bytes ) - added by Paul A. Bristow 8 years ago.

Download all attachments as: .zip

Change History (7)

by Paul A. Bristow, 8 years ago

Attachment: test.cpp added

comment:1 by John Maddock, 8 years ago

With expression templates on, then the return value is an expression template - no calculations have been performed at that point - you have to assign the returned value to something to force the function to be evaluated.

But.... this is probably a big trap for the unwary, so I'll change.

comment:2 by Paul A. Bristow, 8 years ago

I was indeed unwary, and fell straight into the trap :-(

The original problem was within this templated function:

template <int N, class T = double>
T nth_2deriv(T x)
{ // return nth root of x using 1st and 2nd derivatives and Halley.

  //typedef double guess_type; // Works OK with this (and may be accurate enough anyway).
  typedef T guess_type; // Failed with this with cpp_dec_float_50 only.

  int exponent;
  frexp(static_cast<guess_type>(x), &exponent); // Get exponent of z (ignore mantissa).
  T guess = ldexp(static_cast<guess_type>(1.), exponent / N); // Rough guess is to divide the exponent by n.
  T min = ldexp(static_cast<guess_type>(1.) / 2, exponent / N); // Minimum possible value is half our guess.
  T max = ldexp(static_cast<guess_type>(2.), exponent / N); // Maximum possible value is twice our guess.
...

Others may appreciate this trap not existing! Thanks.

comment:3 by anonymous, 8 years ago

But the sample code shows frexp obtaining faulty results for the integer exponent argument. This is not a multiprecision type. I don't understand what the exponent obtained in frexp has to do with et_on or et_off. I'm confused here.

Chris

comment:4 by anonymous, 8 years ago

But the sample code shows frexp obtaining faulty results for the integer exponent argument. This is not a multiprecision type. I don't understand what the exponent obtained in frexp has to do with et_on or et_off. I'm confused here.

The function is never evaluated in the et_on case unless the returned value is assigned to something - so the integer argument remains uninitialized. It's a bug in the expression template code really, will fix shortly. John.

comment:5 by Paul A. Bristow, 8 years ago

I confirm that providing something to take the result of frexp works as predicted.

T mantisssa = frexp(static_cast<guess_type>(x), &exponent);

This provides an easy workaround for the current release 1.56.

(But it is curious the GCC works OK without this when MSVC fails?).

Note: See TracTickets for help on using tickets.