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 // http://en.wikipedia.org/wiki/Quadruple_precision_floating-point_format#Double-double_arithmetic 44 // With some compilers (gcc 4.6.x) on some platforms (powerpc64), 45 // "long double" is implemented as a pair of double: "double double" format. 46 // This causes a problem with epsilon (eps). 47 // eps is the smallest positive number such that 1.0 + eps > 1.0 48 // 49 // Normal format: 1.0 + e = 1.0...01 // N-1 zeros for N fraction bits 50 // D-D format: 1.0 + e = 1.000...0001 // epsilon can be very small 51 // 52 // In the normal format, 1.0 + e has to fit in one stretch of bits. 53 // The maximum rounding error is half of eps. 54 // 55 // In the double-double format, 1.0 + e splits across two doubles: 56 // 1.0 in the high double, e in the low double, and they do not have to 57 // be contiguous. The maximum rounding error on a value close to 1.0 is 58 // much larger than eps. 59 // 60 // Some code checks for errors by comparing a computed value to a golden 61 // value +/- some multiple of the maximum rounding error. The maximum 62 // rounding error is not available so we use eps as an approximation 63 // instead. That fails when long double is in the double-double format. 64 // Therefore, we define kStdError as a multiple of 65 // max(DBL_EPSILON * DBL_EPSILON, kEpsilon) rather than a multiple of kEpsilon. 66 67 #define DEF_FP_LIMITS(Type, PREFIX) \ 68 const Type MathLimits<Type>::kPosMin = PREFIX##_MIN; \ 69 const Type MathLimits<Type>::kPosMax = PREFIX##_MAX; \ 70 const Type MathLimits<Type>::kMin = -MathLimits<Type>::kPosMax; \ 71 const Type MathLimits<Type>::kMax = MathLimits<Type>::kPosMax; \ 72 const Type MathLimits<Type>::kNegMin = -MathLimits<Type>::kPosMin; \ 73 const Type MathLimits<Type>::kNegMax = -MathLimits<Type>::kPosMax; \ 74 const Type MathLimits<Type>::kEpsilon = PREFIX##_EPSILON; \ 75 /* 32 is 5 bits of mantissa error; should be adequate for common errors */ \ 76 const Type MathLimits<Type>::kStdError = \ 77 32 * (DBL_EPSILON * DBL_EPSILON > MathLimits<Type>::kEpsilon \ 78 ? DBL_EPSILON * DBL_EPSILON : MathLimits<Type>::kEpsilon); \ 79 const Type MathLimits<Type>::kNaN = HUGE_VAL - HUGE_VAL; \ 80 const Type MathLimits<Type>::kPosInf = HUGE_VAL; \ 81 const Type MathLimits<Type>::kNegInf = -HUGE_VAL; 82 83 DEF_FP_LIMITS(float, FLT) 84 DEF_FP_LIMITS(double, DBL) 85 DEF_FP_LIMITS(long double, LDBL); 86 87 #undef DEF_FP_LIMITS 88 } // namespace protobuf 89 } // namespace google 90