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