Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.11


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 
35 
37 
38 
39 
40 XALAN_CPP_NAMESPACE_BEGIN
41 
42 
43 
44 XALAN_USING_XERCES(MemoryManager)
45 
46 
47 
48 // A class to help us support IEEE 754.
50 {
51 public:
52 
53  /**
54  * Perform static initialization. See class PlatformSupportInit.
55  *
56  */
57  static void
58  initialize();
59 
60  /**
61  * Perform static shut down. See class PlatformSupportInit.
62  */
63  static void
64  terminate();
65 
66 
67  // Use these functions to determine if a value represents one of these
68  // special values. On some platforms, regular C/C++ operators don't work
69  // as we need them too, so we have these helper functions.
70 
71  /**
72  * Determine if target is not a number
73  *
74  * @param theNumber target number
75  * @return true if target represents the "not a number" value
76  */
77  static bool
78  isNaN(double theNumber)
79  {
80 #if defined(_MSC_VER)
81  return _isnan(theNumber) != 0;
82 #elif defined(XALAN_POSIX2_AVAILABLE) && !defined(CYGWIN) && !defined(MINGW)
83 #if defined(XALAN_NO_STD_NAMESPACE)
84  return isnam(theNumber) != 0;
85 #else
86  return std::isnan(theNumber) != 0;
87 #endif
88 #else
89  return s_NaN == theNumber;
90 #endif
91  }
92 
93  /**
94  * Determine if target is positive infinity
95  *
96  * @param theNumber target number
97  * @return true if target represents the value for positive infinity
98  */
99  static bool
100  isPositiveInfinity(double theNumber)
101  {
102  return s_positiveInfinity == theNumber;
103  }
104 
105  /**
106  * Determine if target is negative infinity
107  *
108  * @param theNumber target number
109  * @return true if target represents the value for negative infinity
110  */
111  static bool
112  isNegativeInfinity(double theNumber)
113  {
114  return s_negativeInfinity == theNumber;
115  }
116 
117  /**
118  * Determine if target is positive 0.
119  *
120  * @param theNumber target number
121  * @return true if target represents the value for positive 0.
122  */
123  static bool
124  isPositiveZero(double theNumber)
125  {
126  return s_positiveZero == theNumber;
127  }
128 
129  /**
130  * Determine if target is negative 0
131  *
132  * @param theNumber target number
133  * @return true if target represents the value for negative 0
134  */
135  static bool
136  isNegativeZero(double theNumber)
137  {
138  return s_negativeZero == theNumber;
139  }
140 
141  // These can be used to initialize values, but should not
142  // be used to do equality comparisons, as == may fail on
143  // some platforms.
144  //
145 
146  /**
147  * Double value that represents "not a number"
148  *
149  * @return "not a number" value
150  */
151  static double
153  {
154  return s_NaN.d;
155  }
156 
157  /**
158  * Double value that represents positive infinity
159  *
160  * @return positive infinity value
161  */
162  static double
164  {
165  return s_positiveInfinity.d;
166  }
167 
168  /**
169  * Double value that represents negative infinity
170  *
171  * @return negative infinity value
172  */
173  static double
175  {
176  return s_negativeInfinity.d;
177  }
178 
179  /**
180  * Compare two double values, taking into account
181  * the fact that we must support IEEE 754
182  *
183  * @param theLHS a number to compare
184  * @param theRHS a number to compare
185  * @return the result of the compare
186  */
187  static bool
188  equal(
189  double theLHS,
190  double theRHS);
191 
192  /**
193  * Compare two double values, taking into account
194  * the fact that we must support IEEE 754
195  *
196  * @param theLHS a number to compare
197  * @param theRHS a number to compare
198  * @return the result of the compare
199  */
200  static bool
202  double theLHS,
203  double theRHS)
204  {
205  return !equal(theLHS, theRHS);
206  }
207 
208  /**
209  * Compare two double values, taking into account
210  * the fact that we must support IEEE 754
211  *
212  * @param theLHS a number to compare
213  * @param theRHS a number to compare
214  * @return the result of the compare
215  */
216  static bool
217  lessThan(
218  double theLHS,
219  double theRHS);
220 
221  /**
222  * Compare two double values, taking into account
223  * the fact that we must support IEEE 754
224  *
225  * @param theLHS a number to compare
226  * @param theRHS a number to compare
227  * @return the result of the compare
228  */
229  static bool
230  lessThanOrEqual(
231  double theLHS,
232  double theRHS);
233 
234  /**
235  * Compare two double values, taking into account
236  * the fact that we must support IEEE 754
237  *
238  * @param theLHS a number to compare
239  * @param theRHS a number to compare
240  * @return the result of the compare
241  */
242  static bool
243  greaterThan(
244  double theLHS,
245  double theRHS);
246 
247  /**
248  * Compare two double values, taking into account
249  * the fact that we must support IEEE 754
250  *
251  * @param theLHS a number to compare
252  * @param theRHS a number to compare
253  * @return the result of the compare
254  */
255  static bool
256  greaterThanOrEqual(
257  double theLHS,
258  double theRHS);
259 
260  /**
261  * Add two double values, taking into account
262  * the fact that we must support IEEE 754
263  *
264  * @param theLHS a number to add
265  * @param theRHS a number to add
266  * @return the result of the addition
267  */
268  static double
269  add(
270  double theLHS,
271  double theRHS);
272 
273  /**
274  * Subtract two double values, taking into account
275  * the fact that we must support IEEE 754
276  *
277  * @param theLHS a number to subtract
278  * @param theRHS a number to subtract
279  * @return the result of the subtraction
280  */
281  static double
282  subtract(
283  double theLHS,
284  double theRHS);
285 
286  /**
287  * Multiply two double values, taking into account
288  * the fact that we must support IEEE 754
289  *
290  * @param theLHS a number to multiply
291  * @param theRHS a number to multiply
292  * @return the result of the multiplication
293  */
294  static double
295  multiply(
296  double theLHS,
297  double theRHS);
298 
299  /**
300  * Divide two double values, taking into account
301  * the fact that we must support IEEE 754
302  *
303  * @param theLHS a number to divide
304  * @param theRHS a number to divide
305  * @return the result of the division
306  */
307  static double
308  divide(
309  double theLHS,
310  double theRHS);
311 
312  /**
313  * Determine the modulus two double values,
314  * taking into account the fact that we must
315  * support IEEE 754
316  *
317  * @param theLHS a number to divide
318  * @param theRHS a number to divide
319  * @return the result of the modulus
320  */
321  static double
322  modulus(
323  double theLHS,
324  double theRHS);
325 
326  /**
327  * Determine the negative of a double value,
328  * taking into account the fact that we must
329  * support IEEE 754
330  *
331  * @param theDouble a number to negate
332  * @return the result of the negation
333  */
334  static double
335  negative(double theDouble);
336 
337  /**
338  * Return the absolute value of theDouble. If theDouble is NaN,
339  * NaN is returned
340  *
341  * @param theDouble a number to fabs
342  * @return the result of the fabs
343  */
344  static double
345  abs(double theDouble);
346 
347  // Some functors to do the same thing. This is for
348  // STL integration...
349  #if defined(XALAN_NO_STD_NAMESPACE)
350  struct equalFunction : public binary_function<const double&, const double&, bool>
351  #else
352  struct equalFunction : public std::binary_function<const double&, const double&, bool>
353  #endif
354  {
355  result_type
357  first_argument_type theLHS,
358  second_argument_type theRHS) const
359  {
360  return equal(theLHS, theRHS);
361  }
362  };
363 
364  #if defined(XALAN_NO_STD_NAMESPACE)
365  struct notEqualFunction : public binary_function<const double&, const double&, bool>
366  #else
367  struct notEqualFunction : public std::binary_function<const double&, const double&, bool>
368  #endif
369  {
370  result_type
372  first_argument_type theLHS,
373  second_argument_type theRHS) const
374  {
375  return notEqual(theLHS, theRHS);
376  }
377  };
378 
379  #if defined(XALAN_NO_STD_NAMESPACE)
380  struct lessThanFunction : public binary_function<const double&, const double&, bool>
381  #else
382  struct lessThanFunction : public std::binary_function<const double&, const double&, bool>
383  #endif
384  {
385  result_type
387  first_argument_type theLHS,
388  second_argument_type theRHS) const
389  {
390  return lessThan(theLHS, theRHS);
391  }
392  };
393 
394  #if defined(XALAN_NO_STD_NAMESPACE)
395  struct lessThanOrEqualFunction : public binary_function<const double&, const double&, bool>
396  #else
397  struct lessThanOrEqualFunction : public std::binary_function<const double&, const double&, bool>
398  #endif
399  {
400  result_type
402  first_argument_type theLHS,
403  second_argument_type theRHS) const
404  {
405  return lessThanOrEqual(theLHS, theRHS);
406  }
407  };
408 
409  #if defined(XALAN_NO_STD_NAMESPACE)
410  struct greaterThanFunction : public binary_function<const double&, const double&, bool>
411  #else
412  struct greaterThanFunction : public std::binary_function<const double&, const double&, bool>
413  #endif
414  {
415  result_type
417  first_argument_type theLHS,
418  second_argument_type theRHS) const
419  {
420  return greaterThan(theLHS, theRHS);
421  }
422  };
423 
424  #if defined(XALAN_NO_STD_NAMESPACE)
425  struct greaterThanOrEqualFunction : public binary_function<const double&, const double&, bool>
426  #else
427  struct greaterThanOrEqualFunction : public std::binary_function<const double&, const double&, bool>
428  #endif
429  {
430  result_type
432  first_argument_type theLHS,
433  second_argument_type theRHS) const
434  {
435  return greaterThanOrEqual(theLHS, theRHS);
436  }
437  };
438 
439  #if defined(XALAN_NO_STD_NAMESPACE)
440  struct addFunction : public binary_function<const double&, const double&, double>
441  #else
442  struct addFunction : public std::binary_function<const double&, const double&, double>
443  #endif
444  {
445  result_type
447  first_argument_type theLHS,
448  second_argument_type theRHS) const
449  {
450  return add(theLHS, theRHS);
451  }
452  };
453 
454  #if defined(XALAN_NO_STD_NAMESPACE)
455  struct subtractFunction : public binary_function<const double&, const double&, double>
456  #else
457  struct subtractFunction : public std::binary_function<const double&, const double&, double>
458  #endif
459  {
460  result_type
462  first_argument_type theLHS,
463  second_argument_type theRHS) const
464  {
465  return subtract(theLHS, theRHS);
466  }
467  };
468 
469  #if defined(XALAN_NO_STD_NAMESPACE)
470  struct multiplyFunction : public binary_function<const double&, const double&, double>
471  #else
472  struct multiplyFunction : public std::binary_function<const double&, const double&, double>
473  #endif
474  {
475  result_type
477  first_argument_type theLHS,
478  second_argument_type theRHS) const
479  {
480  return multiply(theLHS, theRHS);
481  }
482  };
483 
484  #if defined(XALAN_NO_STD_NAMESPACE)
485  struct divideFunction : public binary_function<const double&, const double&, double>
486  #else
487  struct divideFunction : public std::binary_function<const double&, const double&, double>
488  #endif
489  {
490  result_type
492  first_argument_type theLHS,
493  second_argument_type theRHS) const
494  {
495  return divide(theLHS, theRHS);
496  }
497  };
498 
499  #if defined(XALAN_NO_STD_NAMESPACE)
500  struct modulusFunction : public binary_function<const double&, const double&, double>
501  #else
502  struct modulusFunction : public std::binary_function<const double&, const double&, double>
503  #endif
504  {
505  result_type
507  first_argument_type theLHS,
508  second_argument_type theRHS) const
509  {
510  return modulus(theLHS, theRHS);
511  }
512  };
513 
514  #if defined(XALAN_NO_STD_NAMESPACE)
515  struct negativeFunction : public unary_function<const double&, double>
516  #else
517  struct negativeFunction : public std::unary_function<const double&, double>
518  #endif
519  {
520  result_type
521  operator()(argument_type theDouble) const
522  {
523  return negative(theDouble);
524  }
525  };
526 
527  /**
528  * Determine whether or not a string contains
529  * a valid floating point number.
530  *
531  * @param theString The string to check.
532  * @return true if the string is valid, false if not.
533  */
534  static bool
535  isValid(const XalanDOMString& theString);
536 
537  /**
538  * Determine whether or not a string contains
539  * a valid floating point number.
540  *
541  * @param theString The string to check.
542  * @return true if the string is valid, false if not.
543  */
544  static bool
545  isValid(const XalanDOMChar* theString);
546 
547  /**
548  * Convert a string to a double value. Returns
549  * NaN if the string is not a valid floating
550  * point number.
551  *
552  * @param theString The string to convert.
553  * @param theManager The MemoryManager instance to use.
554  * @return The result of the conversion
555  */
556  static double
557  toDouble(
558  const XalanDOMString& theString,
559  MemoryManager& theManager);
560 
561  /**
562  * Convert a string to a double value. Returns
563  * NaN if the string is not a valid floating
564  * point number.
565  *
566  * @param theString The string to convert.
567  * @param theManager The MemoryManager instance to use.
568  * @return The result of the conversion
569  */
570  static double
571  toDouble(
572  const XalanDOMChar* theString,
573  MemoryManager& theManager);
574 
575  /**
576  * Round a number according to the XPath
577  * rules.
578  *
579  * @param theValue The value to round.
580  * @return The result of the rounding
581  */
582  static double
583  round(double theValue);
584 
585  /**
586  * Returns the ceiling of a number according to the XPath
587  * rules.
588  *
589  * @param theValue The value to round.
590  * @return The result of the rounding
591  */
592  static double
593  ceiling(double theValue)
594  {
595 #if defined(XALAN_STRICT_ANSI_HEADERS)
596  return std::ceil(theValue);
597 #else
598  return ceil(theValue);
599 #endif
600  }
601 
602  /**
603  * Returns the floor of a number according to the XPath
604  * rules.
605  *
606  * @param theValue The value to round.
607  * @return The result of the rounding
608  */
609  static double
610  floor(double theValue)
611  {
612 #if defined(XALAN_STRICT_ANSI_HEADERS)
613  return std::floor(theValue);
614 #else
615  return ::floor(theValue);
616 #endif
617  }
618 
620  {
621  double d;
622  struct
623  {
624  unsigned int dw1;
625  unsigned int dw2;
626  } dwords;
627 
628  bool
629  operator==(double theNumber) const
630  {
631  const NumberUnion temp = { theNumber };
632 
633  return dwords.dw1 == temp.dwords.dw1 &&
634  dwords.dw2 == temp.dwords.dw2;
635  }
636  };
637 
638 private:
639 
640 #if defined(XALAN_NO_STD_NUMERIC_LIMITS)
641  static NumberUnion s_NaN;
642 #else
643  static const NumberUnion s_NaN;
644 #endif
645 
646  static const NumberUnion s_positiveInfinity;
647  static const NumberUnion s_negativeInfinity;
648  static const NumberUnion s_positiveZero;
649  static const NumberUnion s_negativeZero;
650 };
651 
652 
653 
654 XALAN_CPP_NAMESPACE_END
655 
656 
657 
658 #endif // DOUBLESUPPORT_HEADER_GUARD_1357924680
static double getNegativeInfinity()
Double value that represents negative infinity.
struct DoubleSupport::NumberUnion::@20 dwords
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
static bool isPositiveInfinity(double theNumber)
Determine if target is positive infinity.
result_type operator()(argument_type theDouble) const
static bool isNegativeZero(double theNumber)
Determine if target is negative 0.
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
static double getNaN()
Double value that represents "not a number".
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
static bool isNegativeInfinity(double theNumber)
Determine if target is negative infinity.
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
static bool isNaN(double theNumber)
Determine if target is not a number.
static double floor(double theValue)
Returns the floor 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...
#define XALAN_PLATFORMSUPPORT_EXPORT
static double getPositiveInfinity()
Double value that represents positive infinity.
static bool isPositiveZero(double theNumber)
Determine if target is positive 0.
XALAN_CPP_NAMESPACE_BEGIN XALAN_USING_XERCES(Locator)
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
result_type operator()(first_argument_type theLHS, second_argument_type theRHS) const
static double ceiling(double theValue)
Returns the ceiling of a number according to the XPath rules.
bool operator==(double theNumber) const

Interpreting class diagrams

Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.

Xalan-C++ XSLT Processor Version 1.11
Copyright © 1999-2012 The Apache Software Foundation.
All Rights Reserved.

Apache Logo