Developer Documentation
NumberParsing.cc
1 /* ========================================================================= *
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 /*===========================================================================*\
43 * *
44 * $Revision: 13620 $ *
45 * $LastChangedBy: moebius $ *
46 * $Date: 2012-02-01 14:51:25 +0100 (Mi, 01 Feb 2012) $ *
47 * *
48 \*===========================================================================*/
49 
50 #include "NumberParsing.hh"
51 #include <cmath>
52 #include <sstream>
53 
54 namespace Utils
55 {
56 
57  float getFloat(QTextStream &_source)
58  {
59  QString rawNumber;
60  _source >> rawNumber;
61  //decimal part > 0
62  float highPart = 0.0f;
63  //decimal part < 0
64  float lowPart = 0.0f;
65  //sign of the decimal
66  float sign = 1.0;
67  //counter to concatenate high and lowaprt
68  int n = 0;
69 
70  QString::Iterator it = rawNumber.begin();
71  QString::Iterator end = rawNumber.end();
72  if(*it == QLatin1Char('-'))
73  {
74  //we have a negative float
75  sign = sign * -1.0;
76  ++it;
77  }
78 
79  for (;it != end;++it)
80  {
81  //we have read a digit
82  if(it->isDigit())
83  {
84  highPart *=10;
85  highPart += it->digitValue();
86  }
87  else
88  {
89  //stop counting the highPart if its not a digit
90  ++it;
91  break;
92  }
93  }
94 
95  for (;it != end;++it)
96  {
97  //we assume to have read a digit
98  if(it->isDigit())
99  {
100  lowPart *=10;
101  lowPart += it->digitValue();
102  ++n;
103  }
104  else
105  {
106  //stop counting the highPart dont increment here!
107  // otherwise we cant detect if we successful converted
108  break;
109  }
110  }
111  // if something went wrong during decoding use the standard decoding
112  if(it != end)
113  {
114  return rawNumber.toFloat();
115  }
116  return sign * (highPart + lowPart / std::pow(10.0,n));
117  }
118 
119  float getFloat(std::istream &_source)
120  {
121  std::string rawNumber;
122  _source >> rawNumber;
123 
124  //decimal part > 0
125  float highPart = 0.0f;
126  //decimal part < 0
127  float lowPart = 0.0f;
128  //sign of the decimal
129  float sign = 1.0;
130  //counter to concatenate high and lowaprt
131  int n = 0;
132 
133  std::string::iterator it = rawNumber.begin();
134  std::string::iterator end = rawNumber.end();
135  if(*it == '-')
136  {
137  //we have a negative float
138  sign = sign * -1.0;
139  ++it;
140  }
141 
142  for (;it != end;++it)
143  {
144  //we have read a digit
145  if(isdigit(*it))
146  {
147  highPart *=10;
148  highPart += (int)(*it - '0');
149  }
150  else
151  {
152  //stop counting the highPart if its not a digit
153  ++it;
154  break;
155  }
156  }
157 
158  for (;it != end;++it)
159  {
160  //we assume to have read a digit
161  if(isdigit(*it))
162  {
163  lowPart *=10;
164  lowPart += (int)(*it - '0');
165  ++n;
166  }
167  else
168  {
169  //stop counting the highPart dont increment here!
170  // otherwise we cant detect if we successful converted
171  break;
172  }
173  }
174  // if something went wrong during decoding use the standard decoding
175  if(it != end)
176  {
177  float fallback;
178  std::stringstream converter;
179  converter<<rawNumber;
180  converter>>fallback;
181  return fallback;
182  }
183  return sign * (highPart + lowPart / std::pow(10.0,n));
184  }
185 
186  double getDouble(QTextStream &_source)
187  {
188  QString rawNumber;
189  _source >> rawNumber;
190  //decimal part > 0
191  double highPart = 0.0f;
192  //decimal part < 0
193  double lowPart = 0.0f;
194  //sign of the decimal
195  double sign = 1.0;
196  //counter to concatenate high and lowaprt
197  int n = 0;
198 
199  QString::Iterator it = rawNumber.begin();
200  QString::Iterator end = rawNumber.end();
201  if(*it == QLatin1Char('-'))
202  {
203  //we have a negative float
204  sign = sign * -1.0;
205  ++it;
206  }
207 
208  for (;it != end;++it)
209  {
210  //we have read a digit
211  if(it->isDigit())
212  {
213  highPart *=10;
214  highPart += it->digitValue();
215  }
216  else
217  {
218  //stop counting the highPart if its not a digit
219  ++it;
220  break;
221  }
222  }
223 
224  for (;it != end;++it)
225  {
226  //we assume to have read a digit
227  if(it->isDigit())
228  {
229  lowPart *=10;
230  lowPart += it->digitValue();
231  ++n;
232  }
233  else
234  {
235  //stop counting the highPart dont increment here!
236  // otherwise we cant detect if we successful converted
237  break;
238  }
239  }
240  // if something went wrong during decoding use the standard decoding
241  if(it != end)
242  {
243  return rawNumber.toDouble();
244  }
245  return sign * (highPart + lowPart / std::pow(10.0,n));
246  }
247 }