LCOV - code coverage report
Current view: top level - src - diy-fp.h (source / functions) Hit Total Coverage
Test: app.info Lines: 18 18 100.0 %
Date: 2019-01-20 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright 2011 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_DIY_FP_H_
       6             : #define V8_DIY_FP_H_
       7             : 
       8             : #include <stdint.h>
       9             : 
      10             : #include "src/base/logging.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15             : // This "Do It Yourself Floating Point" class implements a floating-point number
      16             : // with a uint64 significand and an int exponent. Normalized DiyFp numbers will
      17             : // have the most significant bit of the significand set.
      18             : // Multiplication and Subtraction do not normalize their results.
      19             : // DiyFp are not designed to contain special doubles (NaN and Infinity).
      20             : class DiyFp {
      21             :  public:
      22             :   static const int kSignificandSize = 64;
      23             : 
      24     5357577 :   DiyFp() : f_(0), e_(0) {}
      25           5 :   DiyFp(uint64_t f, int e) : f_(f), e_(e) {}
      26             : 
      27             :   // this = this - other.
      28             :   // The exponents of both numbers must be the same and the significand of this
      29             :   // must be bigger than the significand of other.
      30             :   // The result will not be normalized.
      31             :   void Subtract(const DiyFp& other) {
      32             :     DCHECK(e_ == other.e_);
      33             :     DCHECK(f_ >= other.f_);
      34     4256377 :     f_ -= other.f_;
      35             :   }
      36             : 
      37             :   // Returns a - b.
      38             :   // The exponents of both numbers must be the same and this must be bigger
      39             :   // than other. The result will not be normalized.
      40             :   static DiyFp Minus(const DiyFp& a, const DiyFp& b) {
      41             :     DiyFp result = a;
      42             :     result.Subtract(b);
      43             :     return result;
      44             :   }
      45             : 
      46             : 
      47             :   // this = this * other.
      48             :   void Multiply(const DiyFp& other);
      49             : 
      50             :   // returns a * b;
      51     7390254 :   static DiyFp Times(const DiyFp& a, const DiyFp& b) {
      52     7390254 :     DiyFp result = a;
      53     7390254 :     result.Multiply(b);
      54     7390254 :     return result;
      55             :   }
      56             : 
      57             :   void Normalize() {
      58             :     DCHECK_NE(f_, 0);
      59       91457 :     uint64_t f = f_;
      60             :     int e = e_;
      61             : 
      62             :     // This method is mainly called for normalizing boundaries. In general
      63             :     // boundaries need to be shifted by 10 bits. We thus optimize for this case.
      64             :     const uint64_t k10MSBits = static_cast<uint64_t>(0x3FF) << 54;
      65     4407038 :     while ((f & k10MSBits) == 0) {
      66     2183292 :       f <<= 10;
      67     2183292 :       e -= 10;
      68             :     }
      69     2421836 :     while ((f & kUint64MSB) == 0) {
      70      198090 :       f <<= 1;
      71      198090 :       e--;
      72             :     }
      73       91457 :     f_ = f;
      74       91457 :     e_ = e;
      75             :   }
      76             : 
      77             :   static DiyFp Normalize(const DiyFp& a) {
      78             :     DiyFp result = a;
      79             :     result.Normalize();
      80             :     return result;
      81             :   }
      82             : 
      83             :   uint64_t f() const { return f_; }
      84             :   int e() const { return e_; }
      85             : 
      86          75 :   void set_f(uint64_t new_value) { f_ = new_value; }
      87          75 :   void set_e(int new_value) { e_ = new_value; }
      88             : 
      89             :  private:
      90             :   static const uint64_t kUint64MSB = static_cast<uint64_t>(1) << 63;
      91             : 
      92             :   uint64_t f_;
      93             :   int e_;
      94             : };
      95             : 
      96             : }  // namespace internal
      97             : }  // namespace v8
      98             : 
      99             : #endif  // V8_DIY_FP_H_

Generated by: LCOV version 1.10