1 //
2 // FPETest.cpp
3 //
4 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
5 // and Contributors.
6 //
7 // SPDX-License-Identifier: BSL-1.0
8 //
9
10
11 #include "FPETest.h"
12 #include "CppUnit/TestCaller.h"
13 #include "CppUnit/TestSuite.h"
14 #include "Poco/FPEnvironment.h"
15
16
17 using Poco::FPE;
18
19
FPETest(const std::string & name)20 FPETest::FPETest(const std::string& name): CppUnit::TestCase(name)
21 {
22 }
23
24
~FPETest()25 FPETest::~FPETest()
26 {
27 }
28
29
testClassify()30 void FPETest::testClassify()
31 {
32 {
33 float a = 0.0f;
34 float b = 0.0f;
35 float nan = a/b;
36 float inf = 1.0f/b;
37
38 assertTrue (FPE::isNaN(nan));
39 assertTrue (!FPE::isNaN(a));
40 assertTrue (FPE::isInfinite(inf));
41 assertTrue (!FPE::isInfinite(a));
42 }
43 {
44 double a = 0;
45 double b = 0;
46 double nan = a/b;
47 double inf = 1.0/b;
48
49 assertTrue (FPE::isNaN(nan));
50 assertTrue (!FPE::isNaN(a));
51 assertTrue (FPE::isInfinite(inf));
52 assertTrue (!FPE::isInfinite(a));
53 }
54 }
55
56
57 #if defined(__HP_aCC)
58 #pragma OPTIMIZE OFF
59 #elif defined(_MSC_VER)
60 #pragma optimize("", off)
61 #elif defined(__APPLE__) && defined(POCO_COMPILER_GCC)
62 #pragma GCC optimization_level 0
63 #endif
64
65
mult(double a,double b)66 double mult(double a, double b)
67 {
68 return a*b;
69 }
70
71
div(double a,double b)72 double div(double a, double b)
73 {
74 return a/b;
75 }
76
77
testFlags()78 void FPETest::testFlags()
79 {
80 FPE::clearFlags();
81
82 // some compilers are intelligent enough to optimize the calculations below away.
83 // unfortunately this leads to a failing test, so we have to trick out the
84 // compiler's optimizer a little bit by doing something with the results.
85 volatile double a = 10;
86 volatile double b = 0;
87 volatile double c = div(a, b);
88
89 #if !defined(POCO_NO_FPENVIRONMENT)
90 assertTrue (FPE::isFlag(FPE::FP_DIVIDE_BY_ZERO));
91 #endif
92 assertTrue (FPE::isInfinite(c));
93
94 FPE::clearFlags();
95 a = 1.23456789e210;
96 b = 9.87654321e210;
97 c = mult(a, b);
98 #if !defined(POCO_NO_FPENVIRONMENT)
99 assertTrue (FPE::isFlag(FPE::FP_OVERFLOW));
100 #endif
101 assertEqualDelta(c, c, 0);
102
103 FPE::clearFlags();
104 a = 1.23456789e-99;
105 b = 9.87654321e210;
106 c = div(a, b);
107 #if !defined(POCO_NO_FPENVIRONMENT)
108 assertTrue (FPE::isFlag(FPE::FP_UNDERFLOW));
109 #endif
110 assertEqualDelta(c, c, 0);
111 }
112
113
114 #if defined(__HP_aCC)
115 #pragma OPTIMIZE ON
116 #elif defined(_MSC_VER)
117 #pragma optimize("", on)
118 #elif defined(__APPLE__) && defined(POCO_COMPILER_GCC)
119 #pragma GCC optimization_level reset
120 #endif
121
122
testRound()123 void FPETest::testRound()
124 {
125 #if !defined(__osf__) && !defined(__VMS) && !defined(POCO_NO_FPENVIRONMENT)
126 FPE::setRoundingMode(FPE::FP_ROUND_TONEAREST);
127 assertTrue (FPE::getRoundingMode() == FPE::FP_ROUND_TONEAREST);
128 {
129 FPE env(FPE::FP_ROUND_TOWARDZERO);
130 assertTrue (FPE::getRoundingMode() == FPE::FP_ROUND_TOWARDZERO);
131 }
132 assertTrue (FPE::getRoundingMode() == FPE::FP_ROUND_TONEAREST);
133 #endif
134 }
135
136
setUp()137 void FPETest::setUp()
138 {
139 }
140
141
tearDown()142 void FPETest::tearDown()
143 {
144 }
145
146
suite()147 CppUnit::Test* FPETest::suite()
148 {
149 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("FPETest");
150
151 CppUnit_addTest(pSuite, FPETest, testClassify);
152 CppUnit_addTest(pSuite, FPETest, testFlags);
153 CppUnit_addTest(pSuite, FPETest, testRound);
154
155 return pSuite;
156 }
157