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
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
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
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
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
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
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
#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
struct xalanc::DoubleSupport::NumberUnion::@7 dwords
bool operator==(double theNumber) const