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 namespace v8 { 9 namespace internal { 10 11 // This "Do It Yourself Floating Point" class implements a floating-point number 12 // with a uint64 significand and an int exponent. Normalized DiyFp numbers will 13 // have the most significant bit of the significand set. 14 // Multiplication and Subtraction do not normalize their results. 15 // DiyFp are not designed to contain special doubles (NaN and Infinity). 16 class DiyFp { 17 public: 18 static const int kSignificandSize = 64; 19 DiyFp()20 DiyFp() : f_(0), e_(0) {} DiyFp(uint64_t f,int e)21 DiyFp(uint64_t f, int e) : f_(f), e_(e) {} 22 23 // this = this - other. 24 // The exponents of both numbers must be the same and the significand of this 25 // must be bigger than the significand of other. 26 // The result will not be normalized. Subtract(const DiyFp & other)27 void Subtract(const DiyFp& other) { 28 DCHECK(e_ == other.e_); 29 DCHECK(f_ >= other.f_); 30 f_ -= other.f_; 31 } 32 33 // Returns a - b. 34 // The exponents of both numbers must be the same and this must be bigger 35 // than other. The result will not be normalized. Minus(const DiyFp & a,const DiyFp & b)36 static DiyFp Minus(const DiyFp& a, const DiyFp& b) { 37 DiyFp result = a; 38 result.Subtract(b); 39 return result; 40 } 41 42 43 // this = this * other. 44 void Multiply(const DiyFp& other); 45 46 // returns a * b; Times(const DiyFp & a,const DiyFp & b)47 static DiyFp Times(const DiyFp& a, const DiyFp& b) { 48 DiyFp result = a; 49 result.Multiply(b); 50 return result; 51 } 52 Normalize()53 void Normalize() { 54 DCHECK(f_ != 0); 55 uint64_t f = f_; 56 int e = e_; 57 58 // This method is mainly called for normalizing boundaries. In general 59 // boundaries need to be shifted by 10 bits. We thus optimize for this case. 60 const uint64_t k10MSBits = static_cast<uint64_t>(0x3FF) << 54; 61 while ((f & k10MSBits) == 0) { 62 f <<= 10; 63 e -= 10; 64 } 65 while ((f & kUint64MSB) == 0) { 66 f <<= 1; 67 e--; 68 } 69 f_ = f; 70 e_ = e; 71 } 72 Normalize(const DiyFp & a)73 static DiyFp Normalize(const DiyFp& a) { 74 DiyFp result = a; 75 result.Normalize(); 76 return result; 77 } 78 f()79 uint64_t f() const { return f_; } e()80 int e() const { return e_; } 81 set_f(uint64_t new_value)82 void set_f(uint64_t new_value) { f_ = new_value; } set_e(int new_value)83 void set_e(int new_value) { e_ = new_value; } 84 85 private: 86 static const uint64_t kUint64MSB = static_cast<uint64_t>(1) << 63; 87 88 uint64_t f_; 89 int e_; 90 }; 91 92 } } // namespace v8::internal 93 94 #endif // V8_DIY_FP_H_ 95