Xalan-C++ API Reference 1.12.0
DoubleSupport.hpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18#if !defined(DOUBLESUPPORT_HEADER_GUARD_1357924680)
19#define DOUBLESUPPORT_HEADER_GUARD_1357924680
20
21
22
23// Base include file. Must be first.
25
26
27
28#if defined(_MSC_VER)
29#include <float.h>
30#endif
31#include <cmath>
32#include <functional>
33
34#ifdef XALAN_HAVE_STD_ISNAN
35#include <cmath>
36#else
37#include <math.h>
38#endif
39
40
42
43
44
45namespace XALAN_CPP_NAMESPACE {
46
47
48
49using xercesc::MemoryManager;
50
51
52
53// A class to help us support IEEE 754.
55{
56public:
57
58 /**
59 * Perform static initialization. See class PlatformSupportInit.
60 *
61 */
62 static void
64
65 /**
66 * Perform static shut down. See class PlatformSupportInit.
67 */
68 static void
70
71
72 // Use these functions to determine if a value represents one of these
73 // special values. On some platforms, regular C/C++ operators don't work
74 // as we need them too, so we have these helper functions.
75
76 /**
77 * Determine if target is not a number
78 *
79 * @param theNumber target number
80 * @return true if target represents the "not a number" value
81 */
82 static bool
84 {
85#ifdef XALAN_HAVE_STD_ISNAN
86 return std::isnan(theNumber) != 0;
87#elif XALAN_HAVE_ISNAN
88 return isnan(theNumber) != 0;
89#elif XALAN_HAVE__ISNAN
90 return _isnan(theNumber) != 0;
91#else
92 return s_NaN == theNumber;
93#endif
94 }
95
96 /**
97 * Determine if target is positive infinity
98 *
99 * @param theNumber target number
100 * @return true if target represents the value for positive infinity
101 */
102 static bool
104 {
105 return s_positiveInfinity == theNumber;
106 }
107
108 /**
109 * Determine if target is negative infinity
110 *
111 * @param theNumber target number
112 * @return true if target represents the value for negative infinity
113 */
114 static bool
116 {
117 return s_negativeInfinity == theNumber;
118 }
119
120 /**
121 * Determine if target is positive 0.
122 *
123 * @param theNumber target number
124 * @return true if target represents the value for positive 0.
125 */
126 static bool
128 {
129 return s_positiveZero == theNumber;
130 }
131
132 /**
133 * Determine if target is negative 0
134 *
135 * @param theNumber target number
136 * @return true if target represents the value for negative 0
137 */
138 static bool
140 {
141 return s_negativeZero == theNumber;
142 }
143
144 // These can be used to initialize values, but should not
145 // be used to do equality comparisons, as == may fail on
146 // some platforms.
147 //
148
149 /**
150 * Double value that represents "not a number"
151 *
152 * @return "not a number" value
153 */
154 static double
156 {
157 return s_NaN.d;
158 }
159
160 /**
161 * Double value that represents positive infinity
162 *
163 * @return positive infinity value
164 */
165 static double
167 {
168 return s_positiveInfinity.d;
169 }
170
171 /**
172 * Double value that represents negative infinity
173 *
174 * @return negative infinity value
175 */
176 static double
178 {
179 return s_negativeInfinity.d;
180 }
181
182 /**
183 * Compare two double values, taking into account
184 * the fact that we must support IEEE 754
185 *
186 * @param theLHS a number to compare
187 * @param theRHS a number to compare
188 * @return the result of the compare
189 */
190 static bool
192 double theLHS,
193 double theRHS);
194
195 /**
196 * Compare two double values, taking into account
197 * the fact that we must support IEEE 754
198 *
199 * @param theLHS a number to compare
200 * @param theRHS a number to compare
201 * @return the result of the compare
202 */
203 static bool
205 double theLHS,
206 double theRHS)
207 {
208 return !equal(theLHS, theRHS);
209 }
210
211 /**
212 * Compare two double values, taking into account
213 * the fact that we must support IEEE 754
214 *
215 * @param theLHS a number to compare
216 * @param theRHS a number to compare
217 * @return the result of the compare
218 */
219 static bool
221 double theLHS,
222 double theRHS);
223
224 /**
225 * Compare two double values, taking into account
226 * the fact that we must support IEEE 754
227 *
228 * @param theLHS a number to compare
229 * @param theRHS a number to compare
230 * @return the result of the compare
231 */
232 static bool
234 double theLHS,
235 double theRHS);
236
237 /**
238 * Compare two double values, taking into account
239 * the fact that we must support IEEE 754
240 *
241 * @param theLHS a number to compare
242 * @param theRHS a number to compare
243 * @return the result of the compare
244 */
245 static bool
247 double theLHS,
248 double theRHS);
249
250 /**
251 * Compare two double values, taking into account
252 * the fact that we must support IEEE 754
253 *
254 * @param theLHS a number to compare
255 * @param theRHS a number to compare
256 * @return the result of the compare
257 */
258 static bool
260 double theLHS,
261 double theRHS);
262
263 /**
264 * Add two double values, taking into account
265 * the fact that we must support IEEE 754
266 *
267 * @param theLHS a number to add
268 * @param theRHS a number to add
269 * @return the result of the addition
270 */
271 static double
273 double theLHS,
274 double theRHS);
275
276 /**
277 * Subtract two double values, taking into account
278 * the fact that we must support IEEE 754
279 *
280 * @param theLHS a number to subtract
281 * @param theRHS a number to subtract
282 * @return the result of the subtraction
283 */
284 static double
286 double theLHS,
287 double theRHS);
288
289 /**
290 * Multiply two double values, taking into account
291 * the fact that we must support IEEE 754
292 *
293 * @param theLHS a number to multiply
294 * @param theRHS a number to multiply
295 * @return the result of the multiplication
296 */
297 static double
299 double theLHS,
300 double theRHS);
301
302 /**
303 * Divide two double values, taking into account
304 * the fact that we must support IEEE 754
305 *
306 * @param theLHS a number to divide
307 * @param theRHS a number to divide
308 * @return the result of the division
309 */
310 static double
312 double theLHS,
313 double theRHS);
314
315 /**
316 * Determine the modulus two double values,
317 * taking into account the fact that we must
318 * support IEEE 754
319 *
320 * @param theLHS a number to divide
321 * @param theRHS a number to divide
322 * @return the result of the modulus
323 */
324 static double
326 double theLHS,
327 double theRHS);
328
329 /**
330 * Determine the negative of a double value,
331 * taking into account the fact that we must
332 * support IEEE 754
333 *
334 * @param theDouble a number to negate
335 * @return the result of the negation
336 */
337 static double
339
340 /**
341 * Return the absolute value of theDouble. If theDouble is NaN,
342 * NaN is returned
343 *
344 * @param theDouble a number to fabs
345 * @return the result of the fabs
346 */
347 static double
348 abs(double theDouble);
349
350 // Some functors to do the same thing. This is for
351 // STL integration...
353 {
354 bool
356 const double& theLHS,
357 const double& theRHS) const
358 {
359 return equal(theLHS, theRHS);
360 }
361 };
362
364 {
365 bool
367 const double& theLHS,
368 const double& theRHS) const
369 {
370 return notEqual(theLHS, theRHS);
371 }
372 };
373
375 {
376 bool
378 const double& theLHS,
379 const double& theRHS) const
380 {
381 return lessThan(theLHS, theRHS);
382 }
383 };
384
386 {
387 bool
389 const double& theLHS,
390 const double& theRHS) const
391 {
392 return lessThanOrEqual(theLHS, theRHS);
393 }
394 };
395
397 {
398 bool
400 const double& theLHS,
401 const double& theRHS) const
402 {
403 return greaterThan(theLHS, theRHS);
404 }
405 };
406
408 {
409 bool
411 const double& theLHS,
412 const double& theRHS) const
413 {
414 return greaterThanOrEqual(theLHS, theRHS);
415 }
416 };
417
419 {
420 double
422 const double& theLHS,
423 const double& theRHS) const
424 {
425 return add(theLHS, theRHS);
426 }
427 };
428
430 {
431 double
433 const double& theLHS,
434 const double& theRHS) const
435 {
436 return subtract(theLHS, theRHS);
437 }
438 };
439
441 {
442 double
444 const double& theLHS,
445 const double& theRHS) const
446 {
447 return multiply(theLHS, theRHS);
448 }
449 };
450
452 {
453 double
455 const double& theLHS,
456 const double& theRHS) const
457 {
458 return divide(theLHS, theRHS);
459 }
460 };
461
463 {
464 double
466 const double& theLHS,
467 const double& theRHS) const
468 {
469 return modulus(theLHS, theRHS);
470 }
471 };
472
474 {
475 double
476 operator()(const double& theDouble) const
477 {
478 return negative(theDouble);
479 }
480 };
481
482 /**
483 * Determine whether or not a string contains
484 * a valid floating point number.
485 *
486 * @param theString The string to check.
487 * @return true if the string is valid, false if not.
488 */
489 static bool
491
492 /**
493 * Determine whether or not a string contains
494 * a valid floating point number.
495 *
496 * @param theString The string to check.
497 * @return true if the string is valid, false if not.
498 */
499 static bool
501
502 /**
503 * Convert a string to a double value. Returns
504 * NaN if the string is not a valid floating
505 * point number.
506 *
507 * @param theString The string to convert.
508 * @param theManager The MemoryManager instance to use.
509 * @return The result of the conversion
510 */
511 static double
514 MemoryManager& theManager);
515
516 /**
517 * Convert a string to a double value. Returns
518 * NaN if the string is not a valid floating
519 * point number.
520 *
521 * @param theString The string to convert.
522 * @param theManager The MemoryManager instance to use.
523 * @return The result of the conversion
524 */
525 static double
527 const XalanDOMChar* theString,
528 MemoryManager& theManager);
529
530 /**
531 * Round a number according to the XPath
532 * rules.
533 *
534 * @param theValue The value to round.
535 * @return The result of the rounding
536 */
537 static double
539
540 /**
541 * Returns the ceiling of a number according to the XPath
542 * rules.
543 *
544 * @param theValue The value to round.
545 * @return The result of the rounding
546 */
547 static double
549 {
550 return std::ceil(theValue);
551 }
552
553 /**
554 * Returns the floor of a number according to the XPath
555 * rules.
556 *
557 * @param theValue The value to round.
558 * @return The result of the rounding
559 */
560 static double
562 {
563 return std::floor(theValue);
564 }
565
567 {
568 double d;
569 struct
570 {
571 unsigned int dw1;
572 unsigned int dw2;
573 } dwords;
574
575 bool
576 operator==(double theNumber) const
577 {
578 const NumberUnion temp = { theNumber };
579
580 return dwords.dw1 == temp.dwords.dw1 &&
581 dwords.dw2 == temp.dwords.dw2;
582 }
583 };
584
585private:
586
587 static const NumberUnion s_NaN;
588
589 static const NumberUnion s_positiveInfinity;
590 static const NumberUnion s_negativeInfinity;
591 static const NumberUnion s_positiveZero;
592 static const NumberUnion s_negativeZero;
593};
594
595
596
597}
598
599
600
601#endif // DOUBLESUPPORT_HEADER_GUARD_1357924680
#define XALAN_PLATFORMSUPPORT_EXPORT
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
static bool equal(double theLHS, double theRHS)
Compare two double values, taking into account the fact that we must support IEEE 754.
static double getPositiveInfinity()
Double value that represents positive infinity.
static bool lessThan(double theLHS, double theRHS)
Compare two double values, taking into account the fact that we must support IEEE 754.
static bool isPositiveInfinity(double theNumber)
Determine if target is positive infinity.
static bool lessThanOrEqual(double theLHS, double theRHS)
Compare two double values, taking into account the fact that we must support IEEE 754.
static double getNegativeInfinity()
Double value that represents negative infinity.
static bool isValid(const XalanDOMString &theString)
Determine whether or not a string contains a valid floating point number.
static double divide(double theLHS, double theRHS)
Divide two double values, taking into account the fact that we must support IEEE 754.
static double toDouble(const XalanDOMString &theString, MemoryManager &theManager)
Convert a string to a double value.
static double multiply(double theLHS, double theRHS)
Multiply two double values, taking into account the fact that we must support IEEE 754.
static bool isNaN(double theNumber)
Determine if target is not a number.
static double abs(double theDouble)
Return the absolute value of theDouble.
static void initialize()
Perform static initialization.
static bool isNegativeZero(double theNumber)
Determine if target is negative 0.
static double ceiling(double theValue)
Returns the ceiling of a number according to the XPath rules.
static bool notEqual(double theLHS, double theRHS)
Compare two double values, taking into account the fact that we must support IEEE 754.
static double modulus(double theLHS, double theRHS)
Determine the modulus two double values, taking into account the fact that we must support IEEE 754.
static bool isValid(const XalanDOMChar *theString)
Determine whether or not a string contains a valid floating point number.
static bool isPositiveZero(double theNumber)
Determine if target is positive 0.
static double subtract(double theLHS, double theRHS)
Subtract two double values, taking into account the fact that we must support IEEE 754.
static double round(double theValue)
Round a number according to the XPath rules.
static bool greaterThanOrEqual(double theLHS, double theRHS)
Compare two double values, taking into account the fact that we must support IEEE 754.
static bool isNegativeInfinity(double theNumber)
Determine if target is negative infinity.
static double toDouble(const XalanDOMChar *theString, MemoryManager &theManager)
Convert a string to a double value.
static double negative(double theDouble)
Determine the negative of a double value, taking into account the fact that we must support IEEE 754.
static double add(double theLHS, double theRHS)
Add two double values, taking into account the fact that we must support IEEE 754.
static void terminate()
Perform static shut down.
static double floor(double theValue)
Returns the floor of a number according to the XPath rules.
static double getNaN()
Double value that represents "not a number".
static bool greaterThan(double theLHS, double theRHS)
Compare two double values, taking into account the fact that we must support IEEE 754.
double operator()(const double &theLHS, const double &theRHS) const
double operator()(const double &theLHS, const double &theRHS) const
bool operator()(const double &theLHS, const double &theRHS) const
bool operator()(const double &theLHS, const double &theRHS) const
bool operator()(const double &theLHS, const double &theRHS) const
bool operator()(const double &theLHS, const double &theRHS) const
bool operator()(const double &theLHS, const double &theRHS) const
double operator()(const double &theLHS, const double &theRHS) const
double operator()(const double &theLHS, const double &theRHS) const
double operator()(const double &theDouble) const
bool operator()(const double &theLHS, const double &theRHS) const
double operator()(const double &theLHS, const double &theRHS) const
bool operator==(double theNumber) const