// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// of the accuracy of double there,
// while on other machines we'd
// like to go further down
-#ifdef HAVE_STD_NUMERIC_LIMITS
- const long double tolerance
- = std::max (static_cast<long double>(std::numeric_limits<double>::epsilon() / 100),
- static_cast<long double>(std::numeric_limits<long double>::epsilon() * 5));
+ //
+ // the situation is complicated by
+ // the fact that even if long
+ // double exists and is described
+ // by std::numeric_limits, we may
+ // not actually get the additional
+ // precission. One case where this
+ // happens is on x86, where one can
+ // set hardware flags that disable
+ // long double precision even for
+ // long double variables. these
+ // flags are not usually set, but
+ // for example matlab sets them and
+ // this then breaks deal.II code
+ // that is run as a subroutine to
+ // matlab...
+#ifdef HAVE_STD_NUMERIC_LIMITS
+ const long double
+ long_double_eps = static_cast<long double>(std::numeric_limits<long double>::epsilon()),
+ double_eps = static_cast<long double>(std::numeric_limits<double>::epsilon());
#else
- // well, if there is no <limits>
- // header, then we can do not much
- // better than just checking by
- // hand that long double is not the
- // same as double and set some
- // values by hand
- const long double tolerance
- = (sizeof(long double) != sizeof(double) ? 1.e-19 : 5e-16);
+ const long double
+ long_double_eps = 1.09-19L,
+ double_eps = 2.23-16;
#endif
+ // now check whether long double is
+ // more accurate than double, and
+ // set tolerances accordingly
+ const long double tolerance
+ = (static_cast<long double>(1.0) + long_double_eps != static_cast<long double>(1.0)
+ ?
+ std::max (double_eps / 100, long_double_eps * 5)
+ :
+ double_eps * 5
+ );
+
for (unsigned int i=1; i<=m; ++i)
{
<h3>base</h3>
<ol>
+ <li> <p>Fixed: The <code class="member">QGauss</code> constructor
+ hangs on x86 linux systems when deal.II is run from inside
+ MATLAB. The reason is that while the processor offers long
+ double accuracy, MATLAB switches off support for that inside
+ the CPU. It therefore leaves codes that expect the additional
+ accuracy high and dry. Annoyingly, these codes of course run
+ just fine outside of MATLAB's environment. This behavior leads
+ to an infinite loop inside the QGauss constructor, where we
+ want to use the additional accuracy to compute quadrature
+ points to high precision. To avoid the infinite loop, we now
+ check during runtime whether the extra precision is available,
+ not only at compile time.
+ <br>
+ (Christian Kamm, WB 2006/02/21)
+ </p>
+
<li> <p>Fixed: The <code class="member">ParameterHandler::get_integer</code>
had an erroneous check that the value given for a parameter really
represented an integer. This check always succeeded, even in face of an