15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright 2010 the V8 project authors. All rights reserved. 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Redistribution and use in source and binary forms, with or without 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// modification, are permitted provided that the following conditions are 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// met: 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * Redistributions of source code must retain the above copyright 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// notice, this list of conditions and the following disclaimer. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * Redistributions in binary form must reproduce the above 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// copyright notice, this list of conditions and the following 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// disclaimer in the documentation and/or other materials provided 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// contributors may be used to endorse or promote products derived 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// from this software without specific prior written permission. 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef DOUBLE_CONVERSION_DIY_FP_H_ 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define DOUBLE_CONVERSION_DIY_FP_H_ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "utils.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WTF { 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace double_conversion { 3602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This "Do It Yourself Floating Point" class implements a floating-point number 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // with a uint64 significand and an int exponent. Normalized DiyFp numbers will 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // have the most significant bit of the significand set. 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Multiplication and Subtraction do not normalize their results. 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // DiyFp are not designed to contain special doubles (NaN and Infinity). 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class DiyFp { 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static const int kSignificandSize = 64; 4502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DiyFp() : f_(0), e_(0) {} 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DiyFp(uint64_t f, int e) : f_(f), e_(e) {} 4802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // this = this - other. 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The exponents of both numbers must be the same and the significand of this 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // must be bigger than the significand of other. 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The result will not be normalized. 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void Subtract(const DiyFp& other) { 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(e_ == other.e_); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(f_ >= other.f_); 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) f_ -= other.f_; 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Returns a - b. 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The exponents of both numbers must be the same and this must be bigger 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // than other. The result will not be normalized. 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static DiyFp Minus(const DiyFp& a, const DiyFp& b) { 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DiyFp result = a; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.Subtract(b); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 6802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // this = this * other. 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void Multiply(const DiyFp& other); 7102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // returns a * b; 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static DiyFp Times(const DiyFp& a, const DiyFp& b) { 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DiyFp result = a; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.Multiply(b); 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void Normalize() { 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(f_ != 0); 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint64_t f = f_; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int e = e_; 8302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This method is mainly called for normalizing boundaries. In general 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // boundaries need to be shifted by 10 bits. We thus optimize for this case. 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000); 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while ((f & k10MSBits) == 0) { 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) f <<= 10; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) e -= 10; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while ((f & kUint64MSB) == 0) { 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) f <<= 1; 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) e--; 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) f_ = f; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) e_ = e; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static DiyFp Normalize(const DiyFp& a) { 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DiyFp result = a; 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.Normalize(); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint64_t f() const { return f_; } 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int e() const { return e_; } 10702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void set_f(uint64_t new_value) { f_ = new_value; } 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void set_e(int new_value) { e_ = new_value; } 11002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private: 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static const uint64_t kUint64MSB = UINT64_2PART_C(0x80000000, 00000000); 11302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint64_t f_; 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int e_; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 11702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace double_conversion 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WTF 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // DOUBLE_CONVERSION_DIY_FP_H_ 123