Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkFloatToStringTest.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkTestFixture.h"
18 #include "mitkTestingMacros.h"
19 
20 #include <boost/lexical_cast.hpp>
21 
22 #include "mitkEqual.h"
23 #include <math.h>
24 
25 #include "mitkLog.h"
26 
27 #include <functional>
28 #include <limits>
29 
40 class mitkFloatToStringTestSuite : public mitk::TestFixture
41 {
42  CPPUNIT_TEST_SUITE(mitkFloatToStringTestSuite);
43  MITK_TEST(ConfirmStringValues<float>);
44  MITK_TEST(ConfirmStringValues<double>);
45  MITK_TEST(TestConversions<float>);
46  MITK_TEST(TestConversions<double>);
47  CPPUNIT_TEST_SUITE_END();
48 
49 public:
50  template <typename DATATYPE>
51  void ConfirmNumberToString(DATATYPE number, const std::string &s)
52 
53  {
54  CPPUNIT_ASSERT_EQUAL(boost::lexical_cast<std::string>(number), s);
55  }
56 
57  template <typename DATATYPE>
58  void ConfirmStringToNumber(const std::string &s, DATATYPE number)
59 
60  {
61  CPPUNIT_ASSERT_EQUAL(number, boost::lexical_cast<DATATYPE>(s));
62  }
63 
64  template <typename DATATYPE>
65  void ConfirmStringValues()
66  {
67  // we want to make sure that the following strings will be accepted and returned
68  // by our conversion functions. This must not change in the future to ensure compatibility
69  DATATYPE nan = boost::lexical_cast<DATATYPE>("nan");
70  CPPUNIT_ASSERT_MESSAGE("nan==nan must be false", !(nan == nan));
71  nan = boost::lexical_cast<DATATYPE>("NAN");
72  CPPUNIT_ASSERT_MESSAGE("NAN==NAN must be false", !(nan == nan));
73 
74  std::string s_nan = boost::lexical_cast<std::string>(nan);
75  CPPUNIT_ASSERT_EQUAL(std::string("nan"), s_nan);
76 
77  ConfirmStringToNumber("inf", std::numeric_limits<DATATYPE>::infinity());
78  ConfirmStringToNumber("INF", std::numeric_limits<DATATYPE>::infinity());
79  ConfirmStringToNumber("infinity", std::numeric_limits<DATATYPE>::infinity());
80  ConfirmStringToNumber("INFINITY", std::numeric_limits<DATATYPE>::infinity());
81 
82  ConfirmStringToNumber("-inf", -std::numeric_limits<DATATYPE>::infinity());
83  ConfirmStringToNumber("-INF", -std::numeric_limits<DATATYPE>::infinity());
84  ConfirmStringToNumber("-infinity", -std::numeric_limits<DATATYPE>::infinity());
85  ConfirmStringToNumber("-INFINITY", -std::numeric_limits<DATATYPE>::infinity());
86 
87  ConfirmNumberToString(std::numeric_limits<DATATYPE>::infinity(), "inf");
88  ConfirmNumberToString(-std::numeric_limits<DATATYPE>::infinity(), "-inf");
89  }
90 
91  template <typename DATATYPE>
92  void CheckRoundTrip(DATATYPE number, DATATYPE tolerance)
93  {
94  std::string s = boost::lexical_cast<std::string>(number);
95  DATATYPE number2 = boost::lexical_cast<DATATYPE>(s);
96 
97  CPPUNIT_ASSERT_MESSAGE(std::string("Must not parse string ") + s + " as NaN", number2 == number2);
98  if (tolerance == 0)
99  {
100  CPPUNIT_ASSERT_EQUAL(number, number2);
101  }
102  else // mitk::Equal cannot take 0 as tolerance
103  {
104  CPPUNIT_ASSERT(mitk::Equal(number, number2, tolerance));
105  }
106  }
107 
108  template <typename DATATYPE>
109  void CheckRoundTrip(const std::string &input)
110  {
111  DATATYPE number = boost::lexical_cast<DATATYPE>(input);
112  std::string result = boost::lexical_cast<std::string>(number);
113 
114  // There are normal imprecisions when converting to string
115  // We do only compare if the numeric values match "close enough"
116  DATATYPE number2 = boost::lexical_cast<DATATYPE>(result);
117  CPPUNIT_ASSERT(mitk::Equal(number, number2));
118  }
119 
120  template <typename DATATYPE>
121  void TestConversions()
122  {
123  // we cannot test the NaN roundtrip because nan == nan will never be true
124  CheckRoundTrip<DATATYPE>(std::numeric_limits<DATATYPE>::infinity(), 0.0);
125  CheckRoundTrip<DATATYPE>(-std::numeric_limits<DATATYPE>::infinity(), 0.0);
126 
127  CheckRoundTrip<DATATYPE>(std::numeric_limits<DATATYPE>::denorm_min(), mitk::eps);
128  CheckRoundTrip<DATATYPE>(std::numeric_limits<DATATYPE>::epsilon(), mitk::eps);
129  CheckRoundTrip<DATATYPE>(std::numeric_limits<DATATYPE>::lowest(), mitk::eps);
130  CheckRoundTrip<DATATYPE>(std::numeric_limits<DATATYPE>::min(), mitk::eps);
131  CheckRoundTrip<DATATYPE>(std::numeric_limits<DATATYPE>::max(), mitk::eps);
132  CheckRoundTrip<DATATYPE>(sqrt(2), mitk::eps);
133  CheckRoundTrip<DATATYPE>(0.000000042, mitk::eps);
134  CheckRoundTrip<DATATYPE>(422345678.2345678, mitk::eps);
135  CheckRoundTrip<DATATYPE>(0.0, 0);
136  CheckRoundTrip<DATATYPE>(-0.0, 0);
137 
138  CheckRoundTrip<DATATYPE>("1");
139  CheckRoundTrip<DATATYPE>("1.1");
140  CheckRoundTrip<DATATYPE>("1.12121212");
141  CheckRoundTrip<DATATYPE>("1.1e-2");
142  }
143 
144 }; // class
145 
146 MITK_TEST_SUITE_REGISTRATION(mitkFloatToString)
MITK_TEST_SUITE_REGISTRATION(mitkImageToItk)
#define MITK_TEST(TESTMETHOD)
Adds a test to the current test suite.
Test fixture for parameterized tests.
static T max(T x, T y)
Definition: svm.cpp:70
static T min(T x, T y)
Definition: svm.cpp:67
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
MITKCORE_EXPORT const ScalarType eps