1*0e209d39SAndroid Build Coastguard Worker // © 2018 and later: Unicode, Inc. and others. 2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html 3*0e209d39SAndroid Build Coastguard Worker // 4*0e209d39SAndroid Build Coastguard Worker // From the double-conversion library. Original license: 5*0e209d39SAndroid Build Coastguard Worker // 6*0e209d39SAndroid Build Coastguard Worker // Copyright 2010 the V8 project authors. All rights reserved. 7*0e209d39SAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without 8*0e209d39SAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are 9*0e209d39SAndroid Build Coastguard Worker // met: 10*0e209d39SAndroid Build Coastguard Worker // 11*0e209d39SAndroid Build Coastguard Worker // * Redistributions of source code must retain the above copyright 12*0e209d39SAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer. 13*0e209d39SAndroid Build Coastguard Worker // * Redistributions in binary form must reproduce the above 14*0e209d39SAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following 15*0e209d39SAndroid Build Coastguard Worker // disclaimer in the documentation and/or other materials provided 16*0e209d39SAndroid Build Coastguard Worker // with the distribution. 17*0e209d39SAndroid Build Coastguard Worker // * Neither the name of Google Inc. nor the names of its 18*0e209d39SAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived 19*0e209d39SAndroid Build Coastguard Worker // from this software without specific prior written permission. 20*0e209d39SAndroid Build Coastguard Worker // 21*0e209d39SAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22*0e209d39SAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23*0e209d39SAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24*0e209d39SAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25*0e209d39SAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26*0e209d39SAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27*0e209d39SAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28*0e209d39SAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29*0e209d39SAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30*0e209d39SAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31*0e209d39SAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32*0e209d39SAndroid Build Coastguard Worker 33*0e209d39SAndroid Build Coastguard Worker // ICU PATCH: ifdef around UCONFIG_NO_FORMATTING 34*0e209d39SAndroid Build Coastguard Worker #include "unicode/utypes.h" 35*0e209d39SAndroid Build Coastguard Worker #if !UCONFIG_NO_FORMATTING 36*0e209d39SAndroid Build Coastguard Worker 37*0e209d39SAndroid Build Coastguard Worker #ifndef DOUBLE_CONVERSION_BIGNUM_H_ 38*0e209d39SAndroid Build Coastguard Worker #define DOUBLE_CONVERSION_BIGNUM_H_ 39*0e209d39SAndroid Build Coastguard Worker 40*0e209d39SAndroid Build Coastguard Worker // ICU PATCH: Customize header file paths for ICU. 41*0e209d39SAndroid Build Coastguard Worker 42*0e209d39SAndroid Build Coastguard Worker #include "double-conversion-utils.h" 43*0e209d39SAndroid Build Coastguard Worker 44*0e209d39SAndroid Build Coastguard Worker // ICU PATCH: Wrap in ICU namespace 45*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN 46*0e209d39SAndroid Build Coastguard Worker 47*0e209d39SAndroid Build Coastguard Worker namespace double_conversion { 48*0e209d39SAndroid Build Coastguard Worker 49*0e209d39SAndroid Build Coastguard Worker class Bignum { 50*0e209d39SAndroid Build Coastguard Worker public: 51*0e209d39SAndroid Build Coastguard Worker // 3584 = 128 * 28. We can represent 2^3584 > 10^1000 accurately. 52*0e209d39SAndroid Build Coastguard Worker // This bignum can encode much bigger numbers, since it contains an 53*0e209d39SAndroid Build Coastguard Worker // exponent. 54*0e209d39SAndroid Build Coastguard Worker static const int kMaxSignificantBits = 3584; 55*0e209d39SAndroid Build Coastguard Worker Bignum()56*0e209d39SAndroid Build Coastguard Worker Bignum() : used_bigits_(0), exponent_(0) {} 57*0e209d39SAndroid Build Coastguard Worker 58*0e209d39SAndroid Build Coastguard Worker void AssignUInt16(const uint16_t value); 59*0e209d39SAndroid Build Coastguard Worker void AssignUInt64(uint64_t value); 60*0e209d39SAndroid Build Coastguard Worker void AssignBignum(const Bignum& other); 61*0e209d39SAndroid Build Coastguard Worker 62*0e209d39SAndroid Build Coastguard Worker void AssignDecimalString(const Vector<const char> value); 63*0e209d39SAndroid Build Coastguard Worker void AssignHexString(const Vector<const char> value); 64*0e209d39SAndroid Build Coastguard Worker 65*0e209d39SAndroid Build Coastguard Worker void AssignPowerUInt16(uint16_t base, const int exponent); 66*0e209d39SAndroid Build Coastguard Worker 67*0e209d39SAndroid Build Coastguard Worker void AddUInt64(const uint64_t operand); 68*0e209d39SAndroid Build Coastguard Worker void AddBignum(const Bignum& other); 69*0e209d39SAndroid Build Coastguard Worker // Precondition: this >= other. 70*0e209d39SAndroid Build Coastguard Worker void SubtractBignum(const Bignum& other); 71*0e209d39SAndroid Build Coastguard Worker 72*0e209d39SAndroid Build Coastguard Worker void Square(); 73*0e209d39SAndroid Build Coastguard Worker void ShiftLeft(const int shift_amount); 74*0e209d39SAndroid Build Coastguard Worker void MultiplyByUInt32(const uint32_t factor); 75*0e209d39SAndroid Build Coastguard Worker void MultiplyByUInt64(const uint64_t factor); 76*0e209d39SAndroid Build Coastguard Worker void MultiplyByPowerOfTen(const int exponent); Times10()77*0e209d39SAndroid Build Coastguard Worker void Times10() { return MultiplyByUInt32(10); } 78*0e209d39SAndroid Build Coastguard Worker // Pseudocode: 79*0e209d39SAndroid Build Coastguard Worker // int result = this / other; 80*0e209d39SAndroid Build Coastguard Worker // this = this % other; 81*0e209d39SAndroid Build Coastguard Worker // In the worst case this function is in O(this/other). 82*0e209d39SAndroid Build Coastguard Worker uint16_t DivideModuloIntBignum(const Bignum& other); 83*0e209d39SAndroid Build Coastguard Worker 84*0e209d39SAndroid Build Coastguard Worker bool ToHexString(char* buffer, const int buffer_size) const; 85*0e209d39SAndroid Build Coastguard Worker 86*0e209d39SAndroid Build Coastguard Worker // Returns 87*0e209d39SAndroid Build Coastguard Worker // -1 if a < b, 88*0e209d39SAndroid Build Coastguard Worker // 0 if a == b, and 89*0e209d39SAndroid Build Coastguard Worker // +1 if a > b. 90*0e209d39SAndroid Build Coastguard Worker static int Compare(const Bignum& a, const Bignum& b); Equal(const Bignum & a,const Bignum & b)91*0e209d39SAndroid Build Coastguard Worker static bool Equal(const Bignum& a, const Bignum& b) { 92*0e209d39SAndroid Build Coastguard Worker return Compare(a, b) == 0; 93*0e209d39SAndroid Build Coastguard Worker } LessEqual(const Bignum & a,const Bignum & b)94*0e209d39SAndroid Build Coastguard Worker static bool LessEqual(const Bignum& a, const Bignum& b) { 95*0e209d39SAndroid Build Coastguard Worker return Compare(a, b) <= 0; 96*0e209d39SAndroid Build Coastguard Worker } Less(const Bignum & a,const Bignum & b)97*0e209d39SAndroid Build Coastguard Worker static bool Less(const Bignum& a, const Bignum& b) { 98*0e209d39SAndroid Build Coastguard Worker return Compare(a, b) < 0; 99*0e209d39SAndroid Build Coastguard Worker } 100*0e209d39SAndroid Build Coastguard Worker // Returns Compare(a + b, c); 101*0e209d39SAndroid Build Coastguard Worker static int PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c); 102*0e209d39SAndroid Build Coastguard Worker // Returns a + b == c PlusEqual(const Bignum & a,const Bignum & b,const Bignum & c)103*0e209d39SAndroid Build Coastguard Worker static bool PlusEqual(const Bignum& a, const Bignum& b, const Bignum& c) { 104*0e209d39SAndroid Build Coastguard Worker return PlusCompare(a, b, c) == 0; 105*0e209d39SAndroid Build Coastguard Worker } 106*0e209d39SAndroid Build Coastguard Worker // Returns a + b <= c PlusLessEqual(const Bignum & a,const Bignum & b,const Bignum & c)107*0e209d39SAndroid Build Coastguard Worker static bool PlusLessEqual(const Bignum& a, const Bignum& b, const Bignum& c) { 108*0e209d39SAndroid Build Coastguard Worker return PlusCompare(a, b, c) <= 0; 109*0e209d39SAndroid Build Coastguard Worker } 110*0e209d39SAndroid Build Coastguard Worker // Returns a + b < c PlusLess(const Bignum & a,const Bignum & b,const Bignum & c)111*0e209d39SAndroid Build Coastguard Worker static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) { 112*0e209d39SAndroid Build Coastguard Worker return PlusCompare(a, b, c) < 0; 113*0e209d39SAndroid Build Coastguard Worker } 114*0e209d39SAndroid Build Coastguard Worker private: 115*0e209d39SAndroid Build Coastguard Worker typedef uint32_t Chunk; 116*0e209d39SAndroid Build Coastguard Worker typedef uint64_t DoubleChunk; 117*0e209d39SAndroid Build Coastguard Worker 118*0e209d39SAndroid Build Coastguard Worker static const int kChunkSize = sizeof(Chunk) * 8; 119*0e209d39SAndroid Build Coastguard Worker static const int kDoubleChunkSize = sizeof(DoubleChunk) * 8; 120*0e209d39SAndroid Build Coastguard Worker // With bigit size of 28 we loose some bits, but a double still fits easily 121*0e209d39SAndroid Build Coastguard Worker // into two chunks, and more importantly we can use the Comba multiplication. 122*0e209d39SAndroid Build Coastguard Worker static const int kBigitSize = 28; 123*0e209d39SAndroid Build Coastguard Worker static const Chunk kBigitMask = (1 << kBigitSize) - 1; 124*0e209d39SAndroid Build Coastguard Worker // Every instance allocates kBigitLength chunks on the stack. Bignums cannot 125*0e209d39SAndroid Build Coastguard Worker // grow. There are no checks if the stack-allocated space is sufficient. 126*0e209d39SAndroid Build Coastguard Worker static const int kBigitCapacity = kMaxSignificantBits / kBigitSize; 127*0e209d39SAndroid Build Coastguard Worker EnsureCapacity(const int size)128*0e209d39SAndroid Build Coastguard Worker static void EnsureCapacity(const int size) { 129*0e209d39SAndroid Build Coastguard Worker if (size > kBigitCapacity) { 130*0e209d39SAndroid Build Coastguard Worker DOUBLE_CONVERSION_UNREACHABLE(); 131*0e209d39SAndroid Build Coastguard Worker } 132*0e209d39SAndroid Build Coastguard Worker } 133*0e209d39SAndroid Build Coastguard Worker void Align(const Bignum& other); 134*0e209d39SAndroid Build Coastguard Worker void Clamp(); IsClamped()135*0e209d39SAndroid Build Coastguard Worker bool IsClamped() const { 136*0e209d39SAndroid Build Coastguard Worker return used_bigits_ == 0 || RawBigit(used_bigits_ - 1) != 0; 137*0e209d39SAndroid Build Coastguard Worker } Zero()138*0e209d39SAndroid Build Coastguard Worker void Zero() { 139*0e209d39SAndroid Build Coastguard Worker used_bigits_ = 0; 140*0e209d39SAndroid Build Coastguard Worker exponent_ = 0; 141*0e209d39SAndroid Build Coastguard Worker } 142*0e209d39SAndroid Build Coastguard Worker // Requires this to have enough capacity (no tests done). 143*0e209d39SAndroid Build Coastguard Worker // Updates used_bigits_ if necessary. 144*0e209d39SAndroid Build Coastguard Worker // shift_amount must be < kBigitSize. 145*0e209d39SAndroid Build Coastguard Worker void BigitsShiftLeft(const int shift_amount); 146*0e209d39SAndroid Build Coastguard Worker // BigitLength includes the "hidden" bigits encoded in the exponent. BigitLength()147*0e209d39SAndroid Build Coastguard Worker int BigitLength() const { return used_bigits_ + exponent_; } 148*0e209d39SAndroid Build Coastguard Worker Chunk& RawBigit(const int index); 149*0e209d39SAndroid Build Coastguard Worker const Chunk& RawBigit(const int index) const; 150*0e209d39SAndroid Build Coastguard Worker Chunk BigitOrZero(const int index) const; 151*0e209d39SAndroid Build Coastguard Worker void SubtractTimes(const Bignum& other, const int factor); 152*0e209d39SAndroid Build Coastguard Worker 153*0e209d39SAndroid Build Coastguard Worker // The Bignum's value is value(bigits_buffer_) * 2^(exponent_ * kBigitSize), 154*0e209d39SAndroid Build Coastguard Worker // where the value of the buffer consists of the lower kBigitSize bits of 155*0e209d39SAndroid Build Coastguard Worker // the first used_bigits_ Chunks in bigits_buffer_, first chunk has lowest 156*0e209d39SAndroid Build Coastguard Worker // significant bits. 157*0e209d39SAndroid Build Coastguard Worker int16_t used_bigits_; 158*0e209d39SAndroid Build Coastguard Worker int16_t exponent_; 159*0e209d39SAndroid Build Coastguard Worker Chunk bigits_buffer_[kBigitCapacity]; 160*0e209d39SAndroid Build Coastguard Worker 161*0e209d39SAndroid Build Coastguard Worker DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Bignum); 162*0e209d39SAndroid Build Coastguard Worker }; 163*0e209d39SAndroid Build Coastguard Worker 164*0e209d39SAndroid Build Coastguard Worker } // namespace double_conversion 165*0e209d39SAndroid Build Coastguard Worker 166*0e209d39SAndroid Build Coastguard Worker // ICU PATCH: Close ICU namespace 167*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END 168*0e209d39SAndroid Build Coastguard Worker 169*0e209d39SAndroid Build Coastguard Worker #endif // DOUBLE_CONVERSION_BIGNUM_H_ 170*0e209d39SAndroid Build Coastguard Worker #endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING 171