Uint16WithFraction.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. * Copyright (C) 2011 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef Uint16WithFraction_h
  26. #define Uint16WithFraction_h
  27. #include <wtf/MathExtras.h>
  28. namespace JSC {
  29. // Would be nice if this was a static const member, but the OS X linker
  30. // seems to want a symbol in the binary in that case...
  31. #define oneGreaterThanMaxUInt16 0x10000
  32. // A uint16_t with an infinite precision fraction. Upon overflowing
  33. // the uint16_t range, this class will clamp to oneGreaterThanMaxUInt16.
  34. // This is used in converting the fraction part of a number to a string.
  35. class Uint16WithFraction {
  36. public:
  37. explicit Uint16WithFraction(double number, uint16_t divideByExponent = 0)
  38. {
  39. ASSERT(number && std::isfinite(number) && !std::signbit(number));
  40. // Check for values out of uint16_t range.
  41. if (number >= oneGreaterThanMaxUInt16) {
  42. m_values.append(oneGreaterThanMaxUInt16);
  43. m_leadingZeros = 0;
  44. return;
  45. }
  46. // Append the units to m_values.
  47. double integerPart = floor(number);
  48. m_values.append(static_cast<uint32_t>(integerPart));
  49. bool sign;
  50. int32_t exponent;
  51. uint64_t mantissa;
  52. decomposeDouble(number - integerPart, sign, exponent, mantissa);
  53. ASSERT(!sign && exponent < 0);
  54. exponent -= divideByExponent;
  55. int32_t zeroBits = -exponent;
  56. --zeroBits;
  57. // Append the append words for to m_values.
  58. while (zeroBits >= 32) {
  59. m_values.append(0);
  60. zeroBits -= 32;
  61. }
  62. // Left align the 53 bits of the mantissa within 96 bits.
  63. uint32_t values[3];
  64. values[0] = static_cast<uint32_t>(mantissa >> 21);
  65. values[1] = static_cast<uint32_t>(mantissa << 11);
  66. values[2] = 0;
  67. // Shift based on the remainder of the exponent.
  68. if (zeroBits) {
  69. values[2] = values[1] << (32 - zeroBits);
  70. values[1] = (values[1] >> zeroBits) | (values[0] << (32 - zeroBits));
  71. values[0] = (values[0] >> zeroBits);
  72. }
  73. m_values.append(values[0]);
  74. m_values.append(values[1]);
  75. m_values.append(values[2]);
  76. // Canonicalize; remove any trailing zeros.
  77. while (m_values.size() > 1 && !m_values.last())
  78. m_values.removeLast();
  79. // Count the number of leading zero, this is useful in optimizing multiplies.
  80. m_leadingZeros = 0;
  81. while (m_leadingZeros < m_values.size() && !m_values[m_leadingZeros])
  82. ++m_leadingZeros;
  83. }
  84. Uint16WithFraction& operator*=(uint16_t multiplier)
  85. {
  86. ASSERT(checkConsistency());
  87. // iteratate backwards over the fraction until we reach the leading zeros,
  88. // passing the carry from one calculation into the next.
  89. uint64_t accumulator = 0;
  90. for (size_t i = m_values.size(); i > m_leadingZeros; ) {
  91. --i;
  92. accumulator += static_cast<uint64_t>(m_values[i]) * static_cast<uint64_t>(multiplier);
  93. m_values[i] = static_cast<uint32_t>(accumulator);
  94. accumulator >>= 32;
  95. }
  96. if (!m_leadingZeros) {
  97. // With a multiplicand and multiplier in the uint16_t range, this cannot carry
  98. // (even allowing for the infinity value).
  99. ASSERT(!accumulator);
  100. // Check for overflow & clamp to 'infinity'.
  101. if (m_values[0] >= oneGreaterThanMaxUInt16) {
  102. m_values.shrink(1);
  103. m_values[0] = oneGreaterThanMaxUInt16;
  104. m_leadingZeros = 0;
  105. return *this;
  106. }
  107. } else if (accumulator) {
  108. // Check for carry from the last multiply, if so overwrite last leading zero.
  109. m_values[--m_leadingZeros] = static_cast<uint32_t>(accumulator);
  110. // The limited range of the multiplier should mean that even if we carry into
  111. // the units, we don't need to check for overflow of the uint16_t range.
  112. ASSERT(m_values[0] < oneGreaterThanMaxUInt16);
  113. }
  114. // Multiplication by an even value may introduce trailing zeros; if so, clean them
  115. // up. (Keeping the value in a normalized form makes some of the comparison operations
  116. // more efficient).
  117. while (m_values.size() > 1 && !m_values.last())
  118. m_values.removeLast();
  119. ASSERT(checkConsistency());
  120. return *this;
  121. }
  122. bool operator<(const Uint16WithFraction& other)
  123. {
  124. ASSERT(checkConsistency());
  125. ASSERT(other.checkConsistency());
  126. // Iterate over the common lengths of arrays.
  127. size_t minSize = std::min(m_values.size(), other.m_values.size());
  128. for (size_t index = 0; index < minSize; ++index) {
  129. // If we find a value that is not equal, compare and return.
  130. uint32_t fromThis = m_values[index];
  131. uint32_t fromOther = other.m_values[index];
  132. if (fromThis != fromOther)
  133. return fromThis < fromOther;
  134. }
  135. // If these numbers have the same lengths, they are equal,
  136. // otherwise which ever number has a longer fraction in larger.
  137. return other.m_values.size() > minSize;
  138. }
  139. // Return the floor (non-fractional portion) of the number, clearing this to zero,
  140. // leaving the fractional part unchanged.
  141. uint32_t floorAndSubtract()
  142. {
  143. // 'floor' is simple the integer portion of the value.
  144. uint32_t floor = m_values[0];
  145. // If floor is non-zero,
  146. if (floor) {
  147. m_values[0] = 0;
  148. m_leadingZeros = 1;
  149. while (m_leadingZeros < m_values.size() && !m_values[m_leadingZeros])
  150. ++m_leadingZeros;
  151. }
  152. return floor;
  153. }
  154. // Compare this value to 0.5, returns -1 for less than, 0 for equal, 1 for greater.
  155. int comparePoint5()
  156. {
  157. ASSERT(checkConsistency());
  158. // If units != 0, this is greater than 0.5.
  159. if (m_values[0])
  160. return 1;
  161. // If size == 1 this value is 0, hence < 0.5.
  162. if (m_values.size() == 1)
  163. return -1;
  164. // Compare to 0.5.
  165. if (m_values[1] > 0x80000000ul)
  166. return 1;
  167. if (m_values[1] < 0x80000000ul)
  168. return -1;
  169. // Check for more words - since normalized numbers have no trailing zeros, if
  170. // there are more that two digits we can assume at least one more is non-zero,
  171. // and hence the value is > 0.5.
  172. return m_values.size() > 2 ? 1 : 0;
  173. }
  174. // Return true if the sum of this plus addend would be greater than 1.
  175. bool sumGreaterThanOne(const Uint16WithFraction& addend)
  176. {
  177. ASSERT(checkConsistency());
  178. ASSERT(addend.checkConsistency());
  179. // First, sum the units. If the result is greater than one, return true.
  180. // If equal to one, return true if either number has a fractional part.
  181. uint32_t sum = m_values[0] + addend.m_values[0];
  182. if (sum)
  183. return sum > 1 || std::max(m_values.size(), addend.m_values.size()) > 1;
  184. // We could still produce a result greater than zero if addition of the next
  185. // word from the fraction were to carry, leaving a result > 0.
  186. // Iterate over the common lengths of arrays.
  187. size_t minSize = std::min(m_values.size(), addend.m_values.size());
  188. for (size_t index = 1; index < minSize; ++index) {
  189. // Sum the next word from this & the addend.
  190. uint32_t fromThis = m_values[index];
  191. uint32_t fromAddend = addend.m_values[index];
  192. sum = fromThis + fromAddend;
  193. // Check for overflow. If so, check whether the remaining result is non-zero,
  194. // or if there are any further words in the fraction.
  195. if (sum < fromThis)
  196. return sum || (index + 1) < std::max(m_values.size(), addend.m_values.size());
  197. // If the sum is uint32_t max, then we would carry a 1 if addition of the next
  198. // digits in the number were to overflow.
  199. if (sum != 0xFFFFFFFF)
  200. return false;
  201. }
  202. return false;
  203. }
  204. private:
  205. bool checkConsistency() const
  206. {
  207. // All values should have at least one value.
  208. return (m_values.size())
  209. // The units value must be a uint16_t, or the value is the overflow value.
  210. && (m_values[0] < oneGreaterThanMaxUInt16 || (m_values[0] == oneGreaterThanMaxUInt16 && m_values.size() == 1))
  211. // There should be no trailing zeros (unless this value is zero!).
  212. && (m_values.last() || m_values.size() == 1);
  213. }
  214. // The internal storage of the number. This vector is always at least one entry in size,
  215. // with the first entry holding the portion of the number greater than zero. The first
  216. // value always hold a value in the uint16_t range, or holds the value oneGreaterThanMaxUInt16 to
  217. // indicate the value has overflowed to >= 0x10000. If the units value is oneGreaterThanMaxUInt16,
  218. // there can be no fraction (size must be 1).
  219. //
  220. // Subsequent values in the array represent portions of the fractional part of this number.
  221. // The total value of the number is the sum of (m_values[i] / pow(2^32, i)), for each i
  222. // in the array. The vector should contain no trailing zeros, except for the value '0',
  223. // represented by a vector contianing a single zero value. These constraints are checked
  224. // by 'checkConsistency()', above.
  225. //
  226. // The inline capacity of the vector is set to be able to contain any IEEE double (1 for
  227. // the units column, 32 for zeros introduced due to an exponent up to -3FE, and 2 for
  228. // bits taken from the mantissa).
  229. Vector<uint32_t, 36> m_values;
  230. // Cache a count of the number of leading zeros in m_values. We can use this to optimize
  231. // methods that would otherwise need visit all words in the vector, e.g. multiplication.
  232. size_t m_leadingZeros;
  233. };
  234. }
  235. #endif