1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-23 Bradley M. Bell
// ----------------------------------------------------------------------------
/*
{xrst_begin num_limits.cpp}
Numeric Limits: Example and Test
################################
{xrst_literal
// BEGIN C++
// END C++
}
{xrst_end num_limits.cpp}
*/
// BEGIN C++
# ifdef _MSC_VER
// Supress Microsoft compiler warning about possible loss of precision,
// in the constructors (when converting to std::complex<float>)
// Float one = 1
// Float two = 2
// 1 and 2 are small enough so no loss of precision when converting to float.
# pragma warning(disable:4244)
# endif
# include <cppad/cppad.hpp>
# include <complex>
namespace {
typedef CppAD::AD<double> Float;
//
// -----------------------------------------------------------------
bool check_epsilon(void)
{ bool ok = true;
Float eps = CppAD::numeric_limits<Float>::epsilon();
Float eps2 = eps / 2.0;
Float check = 1.0 + eps;
ok &= 1.0 != check;
check = 1.0 + eps2;
ok &= 1.0 == check;
return ok;
}
// -----------------------------------------------------------------
bool check_min(void)
{ bool ok = true;
Float min = CppAD::numeric_limits<Float>::min();
Float eps = CppAD::numeric_limits<Float>::epsilon();
//
Float match = (min / 100.) * 100.;
ok &= fabs(match / min - 1.0) > 3.0 * eps;
//
match = (min * 100.) / 100.;
ok &= fabs(match / min - 1.0) < 3.0 * eps;
return ok;
}
// -----------------------------------------------------------------
bool check_max(void)
{ bool ok = true;
Float max = CppAD::numeric_limits<Float>::max();
Float eps = CppAD::numeric_limits<Float>::epsilon();
//
Float match = (max * 100.) / 100.;
ok &= fabs(match / max - 1.0) > 3.0 * eps;
//
match = (max / 100.) * 100.;
ok &= fabs(match / max - 1.0) < 3.0 * eps;
return ok;
}
// -----------------------------------------------------------------
bool check_nan(void)
{ bool ok = true;
Float nan = CppAD::numeric_limits<Float>::quiet_NaN();
ok &= nan != nan;
return ok;
}
// -----------------------------------------------------------------
bool check_infinity(void)
{ bool ok = true;
Float inf = CppAD::numeric_limits<Float>::infinity();
Float hun = Float(100);
Float tmp = Float(0);
tmp = inf + hun;
ok &= inf == tmp;
tmp = inf - inf;
ok &= CppAD::isnan( tmp );
return ok;
}
// -----------------------------------------------------------------
bool check_digits10(void)
{ bool ok = true;
Float neg_log_eps =
- log10( CppAD::numeric_limits<Float>::epsilon() );
int ceil_neg_log_eps =
Integer( neg_log_eps );
ok &= ceil_neg_log_eps == CppAD::numeric_limits<Float>::digits10;
return ok;
}
// -----------------------------------------------------------------
bool check_max_digits10(void)
{ bool ok = true;
int max_digits10 = CppAD::numeric_limits<Float>::max_digits10;
Float pi = 4.0 * atan( Float(1.0) );
//
std::stringstream ss;
ss << std::setprecision( max_digits10 ) << pi;
//
Float check = Float( std::atof( ss.str().c_str() ) );
ok &= pi == check;
return ok;
}
}
bool num_limits(void)
{ bool ok = true;
ok &= check_epsilon();
ok &= check_min();
ok &= check_max();
ok &= check_nan();
ok &= check_infinity();
ok &= check_digits10();
ok &= check_max_digits10();
return ok;
}
// END C++
|