1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 // All Rights Reserved. 32 // 33 // Author: Maxim Lifantsev 34 // 35 36 #include <google/protobuf/stubs/mathlimits.h> 37 38 #include <google/protobuf/stubs/common.h> 39 40 namespace google { 41 namespace protobuf { 42 43 // MSVC++ 2005 and older compilers think the header declaration was a 44 // definition, and erroneously flag these as a duplicate definition. 45 #if defined(COMPILER_MSVC) || __cpluscplus < 201103L 46 47 #define DEF_COMMON_LIMITS(Type) 48 #define DEF_UNSIGNED_INT_LIMITS(Type) 49 #define DEF_SIGNED_INT_LIMITS(Type) 50 #define DEF_PRECISION_LIMITS(Type) 51 52 #else 53 54 #define DEF_COMMON_LIMITS(Type) \ 55 const bool MathLimits<Type>::kIsSigned; \ 56 const bool MathLimits<Type>::kIsInteger; \ 57 const int MathLimits<Type>::kMin10Exp; \ 58 const int MathLimits<Type>::kMax10Exp; 59 60 #define DEF_UNSIGNED_INT_LIMITS(Type) \ 61 DEF_COMMON_LIMITS(Type) \ 62 const Type MathLimits<Type>::kPosMin; \ 63 const Type MathLimits<Type>::kPosMax; \ 64 const Type MathLimits<Type>::kMin; \ 65 const Type MathLimits<Type>::kMax; \ 66 const Type MathLimits<Type>::kEpsilon; \ 67 const Type MathLimits<Type>::kStdError; 68 69 #define DEF_SIGNED_INT_LIMITS(Type) \ 70 DEF_UNSIGNED_INT_LIMITS(Type) \ 71 const Type MathLimits<Type>::kNegMin; \ 72 const Type MathLimits<Type>::kNegMax; 73 74 #define DEF_PRECISION_LIMITS(Type) \ 75 const int MathLimits<Type>::kPrecisionDigits; 76 77 #endif // not COMPILER_MSVC 78 79 // http://en.wikipedia.org/wiki/Quadruple_precision_floating-point_format#Double-double_arithmetic 80 // With some compilers (gcc 4.6.x) on some platforms (powerpc64), 81 // "long double" is implemented as a pair of double: "double double" format. 82 // This causes a problem with epsilon (eps). 83 // eps is the smallest positive number such that 1.0 + eps > 1.0 84 // 85 // Normal format: 1.0 + e = 1.0...01 // N-1 zeros for N fraction bits 86 // D-D format: 1.0 + e = 1.000...0001 // epsilon can be very small 87 // 88 // In the normal format, 1.0 + e has to fit in one stretch of bits. 89 // The maximum rounding error is half of eps. 90 // 91 // In the double-double format, 1.0 + e splits across two doubles: 92 // 1.0 in the high double, e in the low double, and they do not have to 93 // be contiguous. The maximum rounding error on a value close to 1.0 is 94 // much larger than eps. 95 // 96 // Some code checks for errors by comparing a computed value to a golden 97 // value +/- some multiple of the maximum rounding error. The maximum 98 // rounding error is not available so we use eps as an approximation 99 // instead. That fails when long double is in the double-double format. 100 // Therefore, we define kStdError as a multiple of 101 // max(DBL_EPSILON * DBL_EPSILON, kEpsilon) rather than a multiple of kEpsilon. 102 103 #define DEF_FP_LIMITS(Type, PREFIX) \ 104 DEF_COMMON_LIMITS(Type) \ 105 const Type MathLimits<Type>::kPosMin = PREFIX##_MIN; \ 106 const Type MathLimits<Type>::kPosMax = PREFIX##_MAX; \ 107 const Type MathLimits<Type>::kMin = -MathLimits<Type>::kPosMax; \ 108 const Type MathLimits<Type>::kMax = MathLimits<Type>::kPosMax; \ 109 const Type MathLimits<Type>::kNegMin = -MathLimits<Type>::kPosMin; \ 110 const Type MathLimits<Type>::kNegMax = -MathLimits<Type>::kPosMax; \ 111 const Type MathLimits<Type>::kEpsilon = PREFIX##_EPSILON; \ 112 /* 32 is 5 bits of mantissa error; should be adequate for common errors */ \ 113 const Type MathLimits<Type>::kStdError = \ 114 32 * (DBL_EPSILON * DBL_EPSILON > MathLimits<Type>::kEpsilon \ 115 ? DBL_EPSILON * DBL_EPSILON : MathLimits<Type>::kEpsilon); \ 116 DEF_PRECISION_LIMITS(Type) \ 117 const Type MathLimits<Type>::kNaN = HUGE_VAL - HUGE_VAL; \ 118 const Type MathLimits<Type>::kPosInf = HUGE_VAL; \ 119 const Type MathLimits<Type>::kNegInf = -HUGE_VAL; 120 121 // The following are *not* casts! 122 DEF_SIGNED_INT_LIMITS(int8) 123 DEF_SIGNED_INT_LIMITS(int16) // NOLINT(readability/casting) 124 DEF_SIGNED_INT_LIMITS(int32) // NOLINT(readability/casting) 125 DEF_SIGNED_INT_LIMITS(int64) // NOLINT(readability/casting) 126 DEF_UNSIGNED_INT_LIMITS(uint8) 127 DEF_UNSIGNED_INT_LIMITS(uint16) // NOLINT(readability/casting) 128 DEF_UNSIGNED_INT_LIMITS(uint32) // NOLINT(readability/casting) 129 DEF_UNSIGNED_INT_LIMITS(uint64) // NOLINT(readability/casting) 130 131 DEF_SIGNED_INT_LIMITS(long int) 132 DEF_UNSIGNED_INT_LIMITS(unsigned long int) 133 134 DEF_FP_LIMITS(float, FLT) 135 DEF_FP_LIMITS(double, DBL) 136 DEF_FP_LIMITS(long double, LDBL); 137 138 #undef DEF_COMMON_LIMITS 139 #undef DEF_SIGNED_INT_LIMITS 140 #undef DEF_UNSIGNED_INT_LIMITS 141 #undef DEF_FP_LIMITS 142 #undef DEF_PRECISION_LIMITS 143 } // namespace protobuf 144 } // namespace google 145