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