Joshua
open source statistical hierarchical phrase-based machine translation system
|
00001 // Copyright 2010 the V8 project authors. All rights reserved. 00002 // Redistribution and use in source and binary forms, with or without 00003 // modification, are permitted provided that the following conditions are 00004 // met: 00005 // 00006 // * Redistributions of source code must retain the above copyright 00007 // notice, this list of conditions and the following disclaimer. 00008 // * Redistributions in binary form must reproduce the above 00009 // copyright notice, this list of conditions and the following 00010 // disclaimer in the documentation and/or other materials provided 00011 // with the distribution. 00012 // * Neither the name of Google Inc. nor the names of its 00013 // contributors may be used to endorse or promote products derived 00014 // from this software without specific prior written permission. 00015 // 00016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00017 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00018 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00019 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00020 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00021 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00026 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 00028 #ifndef DOUBLE_CONVERSION_BIGNUM_H_ 00029 #define DOUBLE_CONVERSION_BIGNUM_H_ 00030 00031 #include "utils.h" 00032 00033 namespace double_conversion { 00034 00035 class Bignum { 00036 public: 00037 // 3584 = 128 * 28. We can represent 2^3584 > 10^1000 accurately. 00038 // This bignum can encode much bigger numbers, since it contains an 00039 // exponent. 00040 static const int kMaxSignificantBits = 3584; 00041 00042 Bignum(); 00043 void AssignUInt16(uint16_t value); 00044 void AssignUInt64(uint64_t value); 00045 void AssignBignum(const Bignum& other); 00046 00047 void AssignDecimalString(Vector<const char> value); 00048 void AssignHexString(Vector<const char> value); 00049 00050 void AssignPowerUInt16(uint16_t base, int exponent); 00051 00052 void AddUInt16(uint16_t operand); 00053 void AddUInt64(uint64_t operand); 00054 void AddBignum(const Bignum& other); 00055 // Precondition: this >= other. 00056 void SubtractBignum(const Bignum& other); 00057 00058 void Square(); 00059 void ShiftLeft(int shift_amount); 00060 void MultiplyByUInt32(uint32_t factor); 00061 void MultiplyByUInt64(uint64_t factor); 00062 void MultiplyByPowerOfTen(int exponent); 00063 void Times10() { return MultiplyByUInt32(10); } 00064 // Pseudocode: 00065 // int result = this / other; 00066 // this = this % other; 00067 // In the worst case this function is in O(this/other). 00068 uint16_t DivideModuloIntBignum(const Bignum& other); 00069 00070 bool ToHexString(char* buffer, int buffer_size) const; 00071 00072 // Returns 00073 // -1 if a < b, 00074 // 0 if a == b, and 00075 // +1 if a > b. 00076 static int Compare(const Bignum& a, const Bignum& b); 00077 static bool Equal(const Bignum& a, const Bignum& b) { 00078 return Compare(a, b) == 0; 00079 } 00080 static bool LessEqual(const Bignum& a, const Bignum& b) { 00081 return Compare(a, b) <= 0; 00082 } 00083 static bool Less(const Bignum& a, const Bignum& b) { 00084 return Compare(a, b) < 0; 00085 } 00086 // Returns Compare(a + b, c); 00087 static int PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c); 00088 // Returns a + b == c 00089 static bool PlusEqual(const Bignum& a, const Bignum& b, const Bignum& c) { 00090 return PlusCompare(a, b, c) == 0; 00091 } 00092 // Returns a + b <= c 00093 static bool PlusLessEqual(const Bignum& a, const Bignum& b, const Bignum& c) { 00094 return PlusCompare(a, b, c) <= 0; 00095 } 00096 // Returns a + b < c 00097 static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) { 00098 return PlusCompare(a, b, c) < 0; 00099 } 00100 private: 00101 typedef uint32_t Chunk; 00102 typedef uint64_t DoubleChunk; 00103 00104 static const int kChunkSize = sizeof(Chunk) * 8; 00105 static const int kDoubleChunkSize = sizeof(DoubleChunk) * 8; 00106 // With bigit size of 28 we loose some bits, but a double still fits easily 00107 // into two chunks, and more importantly we can use the Comba multiplication. 00108 static const int kBigitSize = 28; 00109 static const Chunk kBigitMask = (1 << kBigitSize) - 1; 00110 // Every instance allocates kBigitLength chunks on the stack. Bignums cannot 00111 // grow. There are no checks if the stack-allocated space is sufficient. 00112 static const int kBigitCapacity = kMaxSignificantBits / kBigitSize; 00113 00114 void EnsureCapacity(int size) { 00115 if (size > kBigitCapacity) { 00116 UNREACHABLE(); 00117 } 00118 } 00119 void Align(const Bignum& other); 00120 void Clamp(); 00121 bool IsClamped() const; 00122 void Zero(); 00123 // Requires this to have enough capacity (no tests done). 00124 // Updates used_digits_ if necessary. 00125 // shift_amount must be < kBigitSize. 00126 void BigitsShiftLeft(int shift_amount); 00127 // BigitLength includes the "hidden" digits encoded in the exponent. 00128 int BigitLength() const { return used_digits_ + exponent_; } 00129 Chunk BigitAt(int index) const; 00130 void SubtractTimes(const Bignum& other, int factor); 00131 00132 Chunk bigits_buffer_[kBigitCapacity]; 00133 // A vector backed by bigits_buffer_. This way accesses to the array are 00134 // checked for out-of-bounds errors. 00135 Vector<Chunk> bigits_; 00136 int used_digits_; 00137 // The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize). 00138 int exponent_; 00139 00140 DISALLOW_COPY_AND_ASSIGN(Bignum); 00141 }; 00142 00143 } // namespace double_conversion 00144 00145 #endif // DOUBLE_CONVERSION_BIGNUM_H_