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 
45 namespace XALAN_CPP_NAMESPACE {
46 
47 
48 
49 using xercesc::MemoryManager;
50 
51 
52 
53 // A class to help us support IEEE 754.
55 {
56 public:
57 
58  /**
59  * Perform static initialization. See class PlatformSupportInit.
60  *
61  */
62  static void
63  initialize();
64 
65  /**
66  * Perform static shut down. See class PlatformSupportInit.
67  */
68  static void
69  terminate();
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
83  isNaN(double theNumber)
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
103  isPositiveInfinity(double theNumber)
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
115  isNegativeInfinity(double theNumber)
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
127  isPositiveZero(double theNumber)
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
139  isNegativeZero(double theNumber)
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
191  equal(
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
220  lessThan(
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
233  lessThanOrEqual(
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
246  greaterThan(
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
259  greaterThanOrEqual(
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
272  add(
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
285  subtract(
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
298  multiply(
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
311  divide(
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
325  modulus(
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
338  negative(double theDouble);
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 
418  struct addFunction
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
490  isValid(const XalanDOMString& theString);
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
500  isValid(const XalanDOMChar* theString);
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
512  toDouble(
513  const XalanDOMString& theString,
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
526  toDouble(
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
538  round(double theValue);
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
548  ceiling(double theValue)
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
561  floor(double theValue)
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 
585 private:
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
xalanc::DoubleSupport::multiplyFunction::operator()
double operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:443
xalanc::DoubleSupport::NumberUnion::d
double d
Definition: DoubleSupport.hpp:568
xalanc::DoubleSupport::isNegativeZero
static bool isNegativeZero(double theNumber)
Determine if target is negative 0.
Definition: DoubleSupport.hpp:139
xalanc::DoubleSupport::modulusFunction::operator()
double operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:465
xalanc::DoubleSupport::notEqualFunction::operator()
bool operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:366
XALAN_CPP_NAMESPACE
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
Definition: XalanVersion.hpp:76
xalanc::DoubleSupport::notEqualFunction
Definition: DoubleSupport.hpp:363
xalanc::DoubleSupport::modulusFunction
Definition: DoubleSupport.hpp:462
xalanc::DoubleSupport::isNaN
static bool isNaN(double theNumber)
Determine if target is not a number.
Definition: DoubleSupport.hpp:83
xalanc::DoubleSupport::getNegativeInfinity
static double getNegativeInfinity()
Double value that represents negative infinity.
Definition: DoubleSupport.hpp:177
xalanc::DoubleSupport::NumberUnion::dwords
struct xalanc::DoubleSupport::NumberUnion::@7 dwords
XalanDOMString.hpp
xalanc::DoubleSupport::floor
static double floor(double theValue)
Returns the floor of a number according to the XPath rules.
Definition: DoubleSupport.hpp:561
xalanc::DoubleSupport::equalFunction
Definition: DoubleSupport.hpp:352
xalanc::DoubleSupport::divideFunction
Definition: DoubleSupport.hpp:451
xalanc::DoubleSupport::addFunction
Definition: DoubleSupport.hpp:418
xalanc::DoubleSupport::lessThanOrEqualFunction
Definition: DoubleSupport.hpp:385
xalanc::DoubleSupport::notEqual
static bool notEqual(double theLHS, double theRHS)
Compare two double values, taking into account the fact that we must support IEEE 754.
Definition: DoubleSupport.hpp:204
xalanc::DoubleSupport::getPositiveInfinity
static double getPositiveInfinity()
Double value that represents positive infinity.
Definition: DoubleSupport.hpp:166
xalanc::DoubleSupport::isPositiveInfinity
static bool isPositiveInfinity(double theNumber)
Determine if target is positive infinity.
Definition: DoubleSupport.hpp:103
xalanc::DoubleSupport::NumberUnion
Definition: DoubleSupport.hpp:566
XALAN_PLATFORMSUPPORT_EXPORT
#define XALAN_PLATFORMSUPPORT_EXPORT
Definition: PlatformSupportDefinitions.hpp:35
PlatformSupportDefinitions.hpp
xalanc::DoubleSupport::negativeFunction::operator()
double operator()(const double &theDouble) const
Definition: DoubleSupport.hpp:476
xalanc::DoubleSupport::greaterThanOrEqualFunction::operator()
bool operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:410
xalanc::DoubleSupport::lessThanFunction
Definition: DoubleSupport.hpp:374
xalanc::DoubleSupport::lessThanFunction::operator()
bool operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:377
xalanc::DoubleSupport::equalFunction::operator()
bool operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:355
xalanc::DoubleSupport::subtractFunction
Definition: DoubleSupport.hpp:429
xalanc::DoubleSupport::greaterThanOrEqualFunction
Definition: DoubleSupport.hpp:407
xalanc::DoubleSupport::addFunction::operator()
double operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:421
xalanc::DoubleSupport::negativeFunction
Definition: DoubleSupport.hpp:473
xalanc::DoubleSupport::greaterThanFunction::operator()
bool operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:399
xalanc::DoubleSupport::subtractFunction::operator()
double operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:432
xalanc::DoubleSupport::NumberUnion::dw1
unsigned int dw1
Definition: DoubleSupport.hpp:571
xalanc::DoubleSupport::divideFunction::operator()
double operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:454
xalanc::DoubleSupport::ceiling
static double ceiling(double theValue)
Returns the ceiling of a number according to the XPath rules.
Definition: DoubleSupport.hpp:548
xalanc::DoubleSupport::lessThanOrEqualFunction::operator()
bool operator()(const double &theLHS, const double &theRHS) const
Definition: DoubleSupport.hpp:388
xalanc::DoubleSupport::getNaN
static double getNaN()
Double value that represents "not a number".
Definition: DoubleSupport.hpp:155
xalanc::XalanDOMString
Definition: XalanDOMString.hpp:45
xalanc::DoubleSupport::NumberUnion::operator==
bool operator==(double theNumber) const
Definition: DoubleSupport.hpp:576
xalanc::DoubleSupport::isNegativeInfinity
static bool isNegativeInfinity(double theNumber)
Determine if target is negative infinity.
Definition: DoubleSupport.hpp:115
xalanc::DoubleSupport::greaterThanFunction
Definition: DoubleSupport.hpp:396
xalanc::DoubleSupport::NumberUnion::dw2
unsigned int dw2
Definition: DoubleSupport.hpp:572
xalanc::DoubleSupport::isPositiveZero
static bool isPositiveZero(double theNumber)
Determine if target is positive 0.
Definition: DoubleSupport.hpp:127
xalanc::DoubleSupport
Definition: DoubleSupport.hpp:54
xalanc::DoubleSupport::multiplyFunction
Definition: DoubleSupport.hpp:440