00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one 00003 * or more contributor license agreements. See the NOTICE file 00004 * distributed with this work for additional information 00005 * regarding copyright ownership. The ASF licenses this file 00006 * to you under the Apache License, Version 2.0 (the "License"); 00007 * you may not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, 00014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 #if !defined(DOUBLESUPPORT_HEADER_GUARD_1357924680) 00019 #define DOUBLESUPPORT_HEADER_GUARD_1357924680 00020 00021 00022 00023 // Base include file. Must be first. 00024 #include <xalanc/PlatformSupport/PlatformSupportDefinitions.hpp> 00025 00026 00027 00028 #if defined(_MSC_VER) 00029 #include <float.h> 00030 #endif 00031 #include <cmath> 00032 #include <functional> 00033 00034 00035 00036 #include <xalanc/XalanDOM/XalanDOMString.hpp> 00037 00038 00039 00040 XALAN_CPP_NAMESPACE_BEGIN 00041 00042 00043 00044 XALAN_USING_XERCES(MemoryManager) 00045 00046 00047 00048 // A class to help us support IEEE 754. 00049 class XALAN_PLATFORMSUPPORT_EXPORT DoubleSupport 00050 { 00051 public: 00052 00053 /** 00054 * Perform static initialization. See class PlatformSupportInit. 00055 * 00056 */ 00057 static void 00058 initialize(); 00059 00060 /** 00061 * Perform static shut down. See class PlatformSupportInit. 00062 */ 00063 static void 00064 terminate(); 00065 00066 00067 // Use these functions to determine if a value represents one of these 00068 // special values. On some platforms, regular C/C++ operators don't work 00069 // as we need them too, so we have these helper functions. 00070 00071 /** 00072 * Determine if target is not a number 00073 * 00074 * @param theNumber target number 00075 * @return true if target represents the "not a number" value 00076 */ 00077 static bool 00078 isNaN(double theNumber) 00079 { 00080 #if defined(_MSC_VER) 00081 return _isnan(theNumber) != 0; 00082 #elif defined(XALAN_POSIX2_AVAILABLE) && !defined(CYGWIN) && !defined(MINGW) 00083 #if defined(XALAN_NO_STD_NAMESPACE) 00084 return isnam(theNumber) != 0; 00085 #else 00086 return std::isnan(theNumber) != 0; 00087 #endif 00088 #else 00089 return s_NaN == theNumber; 00090 #endif 00091 } 00092 00093 /** 00094 * Determine if target is positive infinity 00095 * 00096 * @param theNumber target number 00097 * @return true if target represents the value for positive infinity 00098 */ 00099 static bool 00100 isPositiveInfinity(double theNumber) 00101 { 00102 return s_positiveInfinity == theNumber; 00103 } 00104 00105 /** 00106 * Determine if target is negative infinity 00107 * 00108 * @param theNumber target number 00109 * @return true if target represents the value for negative infinity 00110 */ 00111 static bool 00112 isNegativeInfinity(double theNumber) 00113 { 00114 return s_negativeInfinity == theNumber; 00115 } 00116 00117 /** 00118 * Determine if target is positive 0. 00119 * 00120 * @param theNumber target number 00121 * @return true if target represents the value for positive 0. 00122 */ 00123 static bool 00124 isPositiveZero(double theNumber) 00125 { 00126 return s_positiveZero == theNumber; 00127 } 00128 00129 /** 00130 * Determine if target is negative 0 00131 * 00132 * @param theNumber target number 00133 * @return true if target represents the value for negative 0 00134 */ 00135 static bool 00136 isNegativeZero(double theNumber) 00137 { 00138 return s_negativeZero == theNumber; 00139 } 00140 00141 // These can be used to initialize values, but should not 00142 // be used to do equality comparisons, as == may fail on 00143 // some platforms. 00144 // 00145 00146 /** 00147 * Double value that represents "not a number" 00148 * 00149 * @return "not a number" value 00150 */ 00151 static double 00152 getNaN() 00153 { 00154 return s_NaN.d; 00155 } 00156 00157 /** 00158 * Double value that represents positive infinity 00159 * 00160 * @return positive infinity value 00161 */ 00162 static double 00163 getPositiveInfinity() 00164 { 00165 return s_positiveInfinity.d; 00166 } 00167 00168 /** 00169 * Double value that represents negative infinity 00170 * 00171 * @return negative infinity value 00172 */ 00173 static double 00174 getNegativeInfinity() 00175 { 00176 return s_negativeInfinity.d; 00177 } 00178 00179 /** 00180 * Compare two double values, taking into account 00181 * the fact that we must support IEEE 754 00182 * 00183 * @param theLHS a number to compare 00184 * @param theRHS a number to compare 00185 * @return the result of the compare 00186 */ 00187 static bool 00188 equal( 00189 double theLHS, 00190 double theRHS); 00191 00192 /** 00193 * Compare two double values, taking into account 00194 * the fact that we must support IEEE 754 00195 * 00196 * @param theLHS a number to compare 00197 * @param theRHS a number to compare 00198 * @return the result of the compare 00199 */ 00200 static bool 00201 notEqual( 00202 double theLHS, 00203 double theRHS) 00204 { 00205 return !equal(theLHS, theRHS); 00206 } 00207 00208 /** 00209 * Compare two double values, taking into account 00210 * the fact that we must support IEEE 754 00211 * 00212 * @param theLHS a number to compare 00213 * @param theRHS a number to compare 00214 * @return the result of the compare 00215 */ 00216 static bool 00217 lessThan( 00218 double theLHS, 00219 double theRHS); 00220 00221 /** 00222 * Compare two double values, taking into account 00223 * the fact that we must support IEEE 754 00224 * 00225 * @param theLHS a number to compare 00226 * @param theRHS a number to compare 00227 * @return the result of the compare 00228 */ 00229 static bool 00230 lessThanOrEqual( 00231 double theLHS, 00232 double theRHS); 00233 00234 /** 00235 * Compare two double values, taking into account 00236 * the fact that we must support IEEE 754 00237 * 00238 * @param theLHS a number to compare 00239 * @param theRHS a number to compare 00240 * @return the result of the compare 00241 */ 00242 static bool 00243 greaterThan( 00244 double theLHS, 00245 double theRHS); 00246 00247 /** 00248 * Compare two double values, taking into account 00249 * the fact that we must support IEEE 754 00250 * 00251 * @param theLHS a number to compare 00252 * @param theRHS a number to compare 00253 * @return the result of the compare 00254 */ 00255 static bool 00256 greaterThanOrEqual( 00257 double theLHS, 00258 double theRHS); 00259 00260 /** 00261 * Add two double values, taking into account 00262 * the fact that we must support IEEE 754 00263 * 00264 * @param theLHS a number to add 00265 * @param theRHS a number to add 00266 * @return the result of the addition 00267 */ 00268 static double 00269 add( 00270 double theLHS, 00271 double theRHS); 00272 00273 /** 00274 * Subtract two double values, taking into account 00275 * the fact that we must support IEEE 754 00276 * 00277 * @param theLHS a number to subtract 00278 * @param theRHS a number to subtract 00279 * @return the result of the subtraction 00280 */ 00281 static double 00282 subtract( 00283 double theLHS, 00284 double theRHS); 00285 00286 /** 00287 * Multiply two double values, taking into account 00288 * the fact that we must support IEEE 754 00289 * 00290 * @param theLHS a number to multiply 00291 * @param theRHS a number to multiply 00292 * @return the result of the multiplication 00293 */ 00294 static double 00295 multiply( 00296 double theLHS, 00297 double theRHS); 00298 00299 /** 00300 * Divide two double values, taking into account 00301 * the fact that we must support IEEE 754 00302 * 00303 * @param theLHS a number to divide 00304 * @param theRHS a number to divide 00305 * @return the result of the division 00306 */ 00307 static double 00308 divide( 00309 double theLHS, 00310 double theRHS); 00311 00312 /** 00313 * Determine the modulus two double values, 00314 * taking into account the fact that we must 00315 * support IEEE 754 00316 * 00317 * @param theLHS a number to divide 00318 * @param theRHS a number to divide 00319 * @return the result of the modulus 00320 */ 00321 static double 00322 modulus( 00323 double theLHS, 00324 double theRHS); 00325 00326 /** 00327 * Determine the negative of a double value, 00328 * taking into account the fact that we must 00329 * support IEEE 754 00330 * 00331 * @param theDouble a number to negate 00332 * @return the result of the negation 00333 */ 00334 static double 00335 negative(double theDouble); 00336 00337 /** 00338 * Return the absolute value of theDouble. If theDouble is NaN, 00339 * NaN is returned 00340 * 00341 * @param theDouble a number to fabs 00342 * @return the result of the fabs 00343 */ 00344 static double 00345 abs(double theDouble); 00346 00347 // Some functors to do the same thing. This is for 00348 // STL integration... 00349 #if defined(XALAN_NO_STD_NAMESPACE) 00350 struct equalFunction : public binary_function<const double&, const double&, bool> 00351 #else 00352 struct equalFunction : public std::binary_function<const double&, const double&, bool> 00353 #endif 00354 { 00355 result_type 00356 operator()( 00357 first_argument_type theLHS, 00358 second_argument_type theRHS) const 00359 { 00360 return equal(theLHS, theRHS); 00361 } 00362 }; 00363 00364 #if defined(XALAN_NO_STD_NAMESPACE) 00365 struct notEqualFunction : public binary_function<const double&, const double&, bool> 00366 #else 00367 struct notEqualFunction : public std::binary_function<const double&, const double&, bool> 00368 #endif 00369 { 00370 result_type 00371 operator()( 00372 first_argument_type theLHS, 00373 second_argument_type theRHS) const 00374 { 00375 return notEqual(theLHS, theRHS); 00376 } 00377 }; 00378 00379 #if defined(XALAN_NO_STD_NAMESPACE) 00380 struct lessThanFunction : public binary_function<const double&, const double&, bool> 00381 #else 00382 struct lessThanFunction : public std::binary_function<const double&, const double&, bool> 00383 #endif 00384 { 00385 result_type 00386 operator()( 00387 first_argument_type theLHS, 00388 second_argument_type theRHS) const 00389 { 00390 return lessThan(theLHS, theRHS); 00391 } 00392 }; 00393 00394 #if defined(XALAN_NO_STD_NAMESPACE) 00395 struct lessThanOrEqualFunction : public binary_function<const double&, const double&, bool> 00396 #else 00397 struct lessThanOrEqualFunction : public std::binary_function<const double&, const double&, bool> 00398 #endif 00399 { 00400 result_type 00401 operator()( 00402 first_argument_type theLHS, 00403 second_argument_type theRHS) const 00404 { 00405 return lessThanOrEqual(theLHS, theRHS); 00406 } 00407 }; 00408 00409 #if defined(XALAN_NO_STD_NAMESPACE) 00410 struct greaterThanFunction : public binary_function<const double&, const double&, bool> 00411 #else 00412 struct greaterThanFunction : public std::binary_function<const double&, const double&, bool> 00413 #endif 00414 { 00415 result_type 00416 operator()( 00417 first_argument_type theLHS, 00418 second_argument_type theRHS) const 00419 { 00420 return greaterThan(theLHS, theRHS); 00421 } 00422 }; 00423 00424 #if defined(XALAN_NO_STD_NAMESPACE) 00425 struct greaterThanOrEqualFunction : public binary_function<const double&, const double&, bool> 00426 #else 00427 struct greaterThanOrEqualFunction : public std::binary_function<const double&, const double&, bool> 00428 #endif 00429 { 00430 result_type 00431 operator()( 00432 first_argument_type theLHS, 00433 second_argument_type theRHS) const 00434 { 00435 return greaterThanOrEqual(theLHS, theRHS); 00436 } 00437 }; 00438 00439 #if defined(XALAN_NO_STD_NAMESPACE) 00440 struct addFunction : public binary_function<const double&, const double&, double> 00441 #else 00442 struct addFunction : public std::binary_function<const double&, const double&, double> 00443 #endif 00444 { 00445 result_type 00446 operator()( 00447 first_argument_type theLHS, 00448 second_argument_type theRHS) const 00449 { 00450 return add(theLHS, theRHS); 00451 } 00452 }; 00453 00454 #if defined(XALAN_NO_STD_NAMESPACE) 00455 struct subtractFunction : public binary_function<const double&, const double&, double> 00456 #else 00457 struct subtractFunction : public std::binary_function<const double&, const double&, double> 00458 #endif 00459 { 00460 result_type 00461 operator()( 00462 first_argument_type theLHS, 00463 second_argument_type theRHS) const 00464 { 00465 return subtract(theLHS, theRHS); 00466 } 00467 }; 00468 00469 #if defined(XALAN_NO_STD_NAMESPACE) 00470 struct multiplyFunction : public binary_function<const double&, const double&, double> 00471 #else 00472 struct multiplyFunction : public std::binary_function<const double&, const double&, double> 00473 #endif 00474 { 00475 result_type 00476 operator()( 00477 first_argument_type theLHS, 00478 second_argument_type theRHS) const 00479 { 00480 return multiply(theLHS, theRHS); 00481 } 00482 }; 00483 00484 #if defined(XALAN_NO_STD_NAMESPACE) 00485 struct divideFunction : public binary_function<const double&, const double&, double> 00486 #else 00487 struct divideFunction : public std::binary_function<const double&, const double&, double> 00488 #endif 00489 { 00490 result_type 00491 operator()( 00492 first_argument_type theLHS, 00493 second_argument_type theRHS) const 00494 { 00495 return divide(theLHS, theRHS); 00496 } 00497 }; 00498 00499 #if defined(XALAN_NO_STD_NAMESPACE) 00500 struct modulusFunction : public binary_function<const double&, const double&, double> 00501 #else 00502 struct modulusFunction : public std::binary_function<const double&, const double&, double> 00503 #endif 00504 { 00505 result_type 00506 operator()( 00507 first_argument_type theLHS, 00508 second_argument_type theRHS) const 00509 { 00510 return modulus(theLHS, theRHS); 00511 } 00512 }; 00513 00514 #if defined(XALAN_NO_STD_NAMESPACE) 00515 struct negativeFunction : public unary_function<const double&, double> 00516 #else 00517 struct negativeFunction : public std::unary_function<const double&, double> 00518 #endif 00519 { 00520 result_type 00521 operator()(argument_type theDouble) const 00522 { 00523 return negative(theDouble); 00524 } 00525 }; 00526 00527 /** 00528 * Determine whether or not a string contains 00529 * a valid floating point number. 00530 * 00531 * @param theString The string to check. 00532 * @return true if the string is valid, false if not. 00533 */ 00534 static bool 00535 isValid(const XalanDOMString& theString); 00536 00537 /** 00538 * Determine whether or not a string contains 00539 * a valid floating point number. 00540 * 00541 * @param theString The string to check. 00542 * @return true if the string is valid, false if not. 00543 */ 00544 static bool 00545 isValid(const XalanDOMChar* theString); 00546 00547 /** 00548 * Convert a string to a double value. Returns 00549 * NaN if the string is not a valid floating 00550 * point number. 00551 * 00552 * @param theString The string to convert. 00553 * @param theManager The MemoryManager instance to use. 00554 * @return The result of the conversion 00555 */ 00556 static double 00557 toDouble( 00558 const XalanDOMString& theString, 00559 MemoryManager& theManager); 00560 00561 /** 00562 * Convert a string to a double value. Returns 00563 * NaN if the string is not a valid floating 00564 * point number. 00565 * 00566 * @param theString The string to convert. 00567 * @param theManager The MemoryManager instance to use. 00568 * @return The result of the conversion 00569 */ 00570 static double 00571 toDouble( 00572 const XalanDOMChar* theString, 00573 MemoryManager& theManager); 00574 00575 /** 00576 * Round a number according to the XPath 00577 * rules. 00578 * 00579 * @param theValue The value to round. 00580 * @return The result of the rounding 00581 */ 00582 static double 00583 round(double theValue); 00584 00585 /** 00586 * Returns the ceiling of a number according to the XPath 00587 * rules. 00588 * 00589 * @param theValue The value to round. 00590 * @return The result of the rounding 00591 */ 00592 static double 00593 ceiling(double theValue) 00594 { 00595 #if defined(XALAN_STRICT_ANSI_HEADERS) 00596 return std::ceil(theValue); 00597 #else 00598 return ceil(theValue); 00599 #endif 00600 } 00601 00602 /** 00603 * Returns the floor of a number according to the XPath 00604 * rules. 00605 * 00606 * @param theValue The value to round. 00607 * @return The result of the rounding 00608 */ 00609 static double 00610 floor(double theValue) 00611 { 00612 #if defined(XALAN_STRICT_ANSI_HEADERS) 00613 return std::floor(theValue); 00614 #else 00615 return ::floor(theValue); 00616 #endif 00617 } 00618 00619 union NumberUnion 00620 { 00621 double d; 00622 struct 00623 { 00624 unsigned int dw1; 00625 unsigned int dw2; 00626 } dwords; 00627 00628 bool 00629 operator==(double theNumber) const 00630 { 00631 const NumberUnion temp = { theNumber }; 00632 00633 return dwords.dw1 == temp.dwords.dw1 && 00634 dwords.dw2 == temp.dwords.dw2; 00635 } 00636 }; 00637 00638 private: 00639 00640 #if defined(XALAN_NO_STD_NUMERIC_LIMITS) 00641 static NumberUnion s_NaN; 00642 #else 00643 static const NumberUnion s_NaN; 00644 #endif 00645 00646 static const NumberUnion s_positiveInfinity; 00647 static const NumberUnion s_negativeInfinity; 00648 static const NumberUnion s_positiveZero; 00649 static const NumberUnion s_negativeZero; 00650 }; 00651 00652 00653 00654 XALAN_CPP_NAMESPACE_END 00655 00656 00657 00658 #endif // DOUBLESUPPORT_HEADER_GUARD_1357924680
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
Xalan-C++ XSLT Processor Version 1.11 |
|