File: num_limits.cpp

package info (click to toggle)
cppad 2025.00.00.2-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 11,552 kB
  • sloc: cpp: 112,594; sh: 5,972; ansic: 179; python: 71; sed: 12; makefile: 10
file content (130 lines) | stat: -rw-r--r-- 3,908 bytes parent folder | download
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++