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
17using Poco::FPE;
18
19
20FPETest::FPETest(const std::string& rName): CppUnit::TestCase(rName)
21{
22}
23
24
25FPETest::~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
34void 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
73double mult(double a, double b)
74{
75 return a*b;
76}
77
78
79double div(double a, double b)
80{
81 return a/b;
82}
83
84
85void 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
130void 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
145void FPETest::setUp()
146{
147}
148
149
150void FPETest::tearDown()
151{
152}
153
154
155CppUnit::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