LCOV - app.info - js/src/v8-dtoa/double.h

LCOV - code coverage report
| Current view: | directory - js/src/v8-dtoa - double.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 51 | 47 | 92.2 %
| Date: | 2012-07-07 | Functions: | 12 | 11 | 91.7 %

           1                 : // Copyright 2010 the V8 project authors. All rights reserved.
           2                 : // Redistribution and use in source and binary forms, with or without
           3                 : // modification, are permitted provided that the following conditions are
           4                 : // met:
           5                 : //
           6                 : //     * Redistributions of source code must retain the above copyright
           7                 : //       notice, this list of conditions and the following disclaimer.
           8                 : //     * Redistributions in binary form must reproduce the above
           9                 : //       copyright notice, this list of conditions and the following
          10                 : //       disclaimer in the documentation and/or other materials provided
          11                 : //       with the distribution.
          12                 : //     * Neither the name of Google Inc. nor the names of its
          13                 : //       contributors may be used to endorse or promote products derived
          14                 : //       from this software without specific prior written permission.
          15                 : //
          16                 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
          17                 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
          18                 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
          19                 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
          20                 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
          21                 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
          22                 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
          23                 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
          24                 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
          25                 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
          26                 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
          27                 :
          28                 : #ifndef V8_DOUBLE_H_
          29                 : #define V8_DOUBLE_H_
          30                 :
          31                 : #include "diy-fp.h"
          32                 :
          33                 : namespace v8 {
          34                 : namespace internal {
          35                 :
          36                 : // We assume that doubles and uint64_t have the same endianness.
          37         1287040 : static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
          38               0 : static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
          39                 :
          40                 : // Helper functions for doubles.
          41                 : class Double {
          42                 :  public:
          43                 :   static const uint64_t kSignMask = V8_2PART_UINT64_C(0x80000000, 00000000);
          44                 :   static const uint64_t kExponentMask = V8_2PART_UINT64_C(0x7FF00000, 00000000);
          45                 :   static const uint64_t kSignificandMask =
          46                 :       V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF);
          47                 :   static const uint64_t kHiddenBit = V8_2PART_UINT64_C(0x00100000, 00000000);
          48                 :
          49                 :   Double() : d64_(0) {}
          50         1287040 :   explicit Double(double d) : d64_(double_to_uint64(d)) {}
          51                 :   explicit Double(uint64_t d64) : d64_(d64) {}
          52                 :
          53          257408 :   DiyFp AsDiyFp() const {
          54          257408 :     ASSERT(!IsSpecial());
          55          257408 :     return DiyFp(Significand(), Exponent());
          56                 :   }
          57                 :
          58                 :   // this->Significand() must not be 0.
          59          257408 :   DiyFp AsNormalizedDiyFp() const {
          60          257408 :     uint64_t f = Significand();
          61          257408 :     int e = Exponent();
          62                 :
          63          257408 :     ASSERT(f != 0);
          64                 :
          65                 :     // The current double could be a denormal.
          66          514816 :     while ((f & kHiddenBit) == 0) {
          67               0 :       f <<= 1;
          68               0 :       e--;
          69                 :     }
          70                 :     // Do the final shifts in one go. Don't forget the hidden bit (the '-1').
          71          257408 :     f <<= DiyFp::kSignificandSize - kSignificandSize - 1;
          72          257408 :     e -= DiyFp::kSignificandSize - kSignificandSize - 1;
          73          257408 :     return DiyFp(f, e);
          74                 :   }
          75                 :
          76                 :   // Returns the double's bit as uint64.
          77         3088896 :   uint64_t AsUint64() const {
          78         3088896 :     return d64_;
          79                 :   }
          80                 :
          81          514816 :   int Exponent() const {
          82          514816 :     if (IsDenormal()) return kDenormalExponent;
          83                 :
          84          514816 :     uint64_t d64 = AsUint64();
          85          514816 :     int biased_e = static_cast<int>((d64 & kExponentMask) >> kSignificandSize);
          86          514816 :     return biased_e - kExponentBias;
          87                 :   }
          88                 :
          89          514816 :   uint64_t Significand() const {
          90          514816 :     uint64_t d64 = AsUint64();
          91          514816 :     uint64_t significand = d64 & kSignificandMask;
          92          514816 :     if (!IsDenormal()) {
          93          514816 :       return significand + kHiddenBit;
          94                 :     } else {
          95               0 :       return significand;
          96                 :     }
          97                 :   }
          98                 :
          99                 :   // Returns true if the double is a denormal.
         100         1029632 :   bool IsDenormal() const {
         101         1029632 :     uint64_t d64 = AsUint64();
         102         1029632 :     return (d64 & kExponentMask) == 0;
         103                 :   }
         104                 :
         105                 :   // We consider denormals not to be special.
         106                 :   // Hence only Infinity and NaN are special.
         107          772224 :   bool IsSpecial() const {
         108          772224 :     uint64_t d64 = AsUint64();
         109          772224 :     return (d64 & kExponentMask) == kExponentMask;
         110                 :   }
         111                 :
         112                 :   bool IsNan() const {
         113                 :     uint64_t d64 = AsUint64();
         114                 :     return ((d64 & kExponentMask) == kExponentMask) &&
         115                 :         ((d64 & kSignificandMask) != 0);
         116                 :   }
         117                 :
         118                 :
         119                 :   bool IsInfinite() const {
         120                 :     uint64_t d64 = AsUint64();
         121                 :     return ((d64 & kExponentMask) == kExponentMask) &&
         122                 :         ((d64 & kSignificandMask) == 0);
         123                 :   }
         124                 :
         125                 :
         126          257408 :   int Sign() const {
         127          257408 :     uint64_t d64 = AsUint64();
         128          257408 :     return (d64 & kSignMask) == 0? 1: -1;
         129                 :   }
         130                 :
         131                 :
         132                 :   // Returns the two boundaries of this.
         133                 :   // The bigger boundary (m_plus) is normalized. The lower boundary has the same
         134                 :   // exponent as m_plus.
         135          257408 :   void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
         136          257408 :     DiyFp v = this->AsDiyFp();
         137          257408 :     bool significand_is_zero = (v.f() == kHiddenBit);
         138          257408 :     DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
         139          257408 :     DiyFp m_minus;
         140          257408 :     if (significand_is_zero && v.e() != kDenormalExponent) {
         141                 :       // The boundary is closer. Think of v = 1000e10 and v- = 9999e9.
         142                 :       // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
         143                 :       // at a distance of 1e8.
         144                 :       // The only exception is for the smallest normal: the largest denormal is
         145                 :       // at the same distance as its successor.
         146                 :       // Note: denormals have the same exponent as the smallest normals.
         147            2980 :       m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
         148                 :     } else {
         149          254428 :       m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
         150                 :     }
         151          257408 :     m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
         152          257408 :     m_minus.set_e(m_plus.e());
         153          257408 :     *out_m_plus = m_plus;
         154          257408 :     *out_m_minus = m_minus;
         155          257408 :   }
         156                 :
         157                 :   double value() const { return uint64_to_double(d64_); }
         158                 :
         159                 :  private:
         160                 :   static const int kSignificandSize = 52;  // Excludes the hidden bit.
         161                 :   static const int kExponentBias = 0x3FF + kSignificandSize;
         162                 :   static const int kDenormalExponent = -kExponentBias + 1;
         163                 :
         164                 :   uint64_t d64_;
         165                 : };
         166                 :
         167                 : } }  // namespace v8::internal
         168                 :
         169                 : #endif  // V8_DOUBLE_H_

Generated by: LCOV version 1.7