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