source: trunk/test_more/limits.cpp @ 2756

Last change on this file since 2756 was 2756, checked in by bradbell, 7 years ago

Make testing of numeric limits more robust by
using external functions, instead of arrays, for storing temporary values.

extern_value.cpp: external functions for getting and setting values.

  • Property svn:keywords set to Id
File size: 4.9 KB
Line 
1/* $Id: limits.cpp 2756 2013-02-27 18:49:28Z bradbell $ */
2/* --------------------------------------------------------------------------
3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
4
5CppAD is distributed under multiple licenses. This distribution is under
6the terms of the
7                    Eclipse Public License Version 1.0.
8
9A copy of this license is included in the COPYING file of this distribution.
10Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
11-------------------------------------------------------------------------- */
12
13/*
14$begin limits.cpp$$
15$spell
16$$
17
18$section Numeric Limits: Example and Test$$
19$index limits$$
20$index example, limits$$
21$index test, limits$$
22
23$head Assumption$$
24This code assumes that the decimal point is infront of the mantissa.
25Hence dividing the minimum normalized value looses precision,
26while multiplying the maximum normalized value results in infinity.
27
28$head Externals$$
29This example using external routines to get and set values
30so that the complier does not set the correspdong code and optimize
31it out.
32
33$code
34$verbatim%example/limits.cpp%0%// BEGIN C++%// END C++%1%$$
35$$
36
37$end
38*/
39// BEGIN C++
40
41# ifdef _MSC_VER
42// Supress Microsoft compiler warning about possible loss of precision,
43// in the constructors (when converting to std::complex<float>)
44//      Type one = 1
45//      Type two = 2
46// 1 and 2 are small enough so no loss of precision when converting to float.
47# pragma warning(disable:4244)
48# endif
49
50# include <cppad/cppad.hpp>
51# include <complex>
52# include "extern_value.hpp"
53
54namespace {
55        using CppAD::vector;
56        using CppAD::abs_geq;
57
58        template <class Type>
59        Type add_one(const Type& value)
60        {       return( Type(1) + value ); }
61        // -----------------------------------------------------------------
62        template <class Type>
63        bool check_epsilon(void)
64        {       bool ok    = true;
65                typedef extern_value<Type> value;
66                value eps( CppAD::numeric_limits<Type>::epsilon() );
67                value one( Type(1) );
68                value two( Type(2) );
69                value tmp( Type(0) );
70                //
71                tmp.set( add_one( eps.get() / two.get() ) ); 
72                ok        &= one.get() == tmp.get();
73                //
74                tmp.set( add_one( eps.get() ) ); 
75                ok        &= one.get() != tmp.get();
76                return ok;
77        }
78        // -----------------------------------------------------------------
79        template <class Type>
80        bool check_min(void)
81        {       bool ok    = true;
82                typedef extern_value<Type> value;
83                value min( CppAD::numeric_limits<Type>::min() );
84                value eps3( Type(3) * CppAD::numeric_limits<Type>::epsilon() );
85                value one( Type(1) );
86                value hun( Type(100) );
87                value tmp( Type(0) );
88                //
89                tmp.set( min.get() / hun.get() );
90                tmp.set( tmp.get() * hun.get() );
91                ok        &= abs_geq(tmp.get()/min.get() - one.get(), eps3.get());
92                //
93                tmp.set( min.get() * hun.get() );
94                tmp.set( tmp.get() / hun.get() );
95                ok        &= ! abs_geq(tmp.get()/min.get() - one.get(), eps3.get());
96                return ok;
97        }
98
99        // -----------------------------------------------------------------
100        template <class Type>
101        bool check_max(void)
102        {       bool ok    = true;
103                typedef extern_value<Type> value;
104                value max2( CppAD::numeric_limits<Type>::max() / Type(2) );
105                value eps3( Type(3) * CppAD::numeric_limits<Type>::epsilon() );
106                value one( Type(1) );
107                value hun( Type(100) );
108                value tmp( Type(0) );
109                //
110                tmp.set( max2.get() * hun.get() );
111                tmp.set( tmp.get() / hun.get() );
112                // tmp is infinite
113                ok        &= abs_geq(tmp.get() / max2.get() - one.get(), eps3.get() );
114                //
115                tmp.set( max2.get() / hun.get() );
116                tmp.set( tmp.get() * hun.get() );
117                ok        &= ! abs_geq(tmp.get() / max2.get() - one.get(), eps3.get() );
118                return ok;
119        }
120}
121
122bool limits(void)
123{       bool ok = true;
124        using CppAD::AD;
125
126        // -------------------------------------------------------------------
127        // epsilon for Base types defined by CppAD
128        ok &= check_epsilon<float>();
129        ok &= check_epsilon<double>();
130        ok &= check_epsilon< std::complex<float> >();
131        ok &= check_epsilon< std::complex<double> >();
132
133        // epsilon for some AD types.
134        ok &= check_epsilon< AD<float> >();
135        ok &= check_epsilon< AD<double> >();
136        ok &= check_epsilon<  AD<std::complex<float> > >();
137        ok &= check_epsilon<  AD<std::complex<double> > >();
138
139        // -------------------------------------------------------------------
140        // min for Base types defined by CppAD
141        ok &= check_min<float>();
142        ok &= check_min<double>();
143        ok &= check_min< std::complex<float> >();
144        ok &= check_min< std::complex<double> >();
145
146        // min for some AD types.
147        ok &= check_min< AD<float> >();
148        ok &= check_min< AD<double> >();
149        ok &= check_min<  AD<std::complex<float> > >();
150        ok &= check_min<  AD<std::complex<double> > >();
151
152        // -------------------------------------------------------------------
153        // max for Base types defined by CppAD
154        ok &= check_max<float>();
155        ok &= check_max<double>();
156        ok &= check_max< std::complex<float> >();
157        ok &= check_max< std::complex<double> >();
158
159        // max for some AD types.
160        ok &= check_max< AD<float> >();
161        ok &= check_max< AD<double> >();
162        ok &= check_max< AD< std::complex<float> > >();
163        ok &= check_max< AD< std::complex<double> > >();
164
165        return ok;
166}
167// END C++
Note: See TracBrowser for help on using the repository browser.