Decimal.cpp 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  1. /*
  2. * Copyright (C) 2012 Google 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 are
  6. * met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above
  11. * copyright notice, this list of conditions and the following disclaimer
  12. * in the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Google Inc. nor the names of its
  15. * contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "Decimal.h"
  31. #include "moz-decimal-utils.h"
  32. using namespace moz_decimal_utils;
  33. #include <algorithm>
  34. #include <float.h>
  35. namespace blink {
  36. namespace DecimalPrivate {
  37. static int const ExponentMax = 1023;
  38. static int const ExponentMin = -1023;
  39. static int const Precision = 18;
  40. static const uint64_t MaxCoefficient = UINT64_C(0xDE0B6B3A763FFFF); // 999999999999999999 == 18 9's
  41. // This class handles Decimal special values.
  42. class SpecialValueHandler {
  43. STACK_ALLOCATED();
  44. WTF_MAKE_NONCOPYABLE(SpecialValueHandler);
  45. public:
  46. enum HandleResult {
  47. BothFinite,
  48. BothInfinity,
  49. EitherNaN,
  50. LHSIsInfinity,
  51. RHSIsInfinity,
  52. };
  53. SpecialValueHandler(const Decimal& lhs, const Decimal& rhs);
  54. HandleResult handle();
  55. Decimal value() const;
  56. private:
  57. enum Result {
  58. ResultIsLHS,
  59. ResultIsRHS,
  60. ResultIsUnknown,
  61. };
  62. const Decimal& m_lhs;
  63. const Decimal& m_rhs;
  64. Result m_result;
  65. };
  66. SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs)
  67. : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown)
  68. {
  69. }
  70. SpecialValueHandler::HandleResult SpecialValueHandler::handle()
  71. {
  72. if (m_lhs.isFinite() && m_rhs.isFinite())
  73. return BothFinite;
  74. const Decimal::EncodedData::FormatClass lhsClass = m_lhs.value().formatClass();
  75. const Decimal::EncodedData::FormatClass rhsClass = m_rhs.value().formatClass();
  76. if (lhsClass == Decimal::EncodedData::ClassNaN) {
  77. m_result = ResultIsLHS;
  78. return EitherNaN;
  79. }
  80. if (rhsClass == Decimal::EncodedData::ClassNaN) {
  81. m_result = ResultIsRHS;
  82. return EitherNaN;
  83. }
  84. if (lhsClass == Decimal::EncodedData::ClassInfinity)
  85. return rhsClass == Decimal::EncodedData::ClassInfinity ? BothInfinity : LHSIsInfinity;
  86. if (rhsClass == Decimal::EncodedData::ClassInfinity)
  87. return RHSIsInfinity;
  88. ASSERT_NOT_REACHED();
  89. return BothFinite;
  90. }
  91. Decimal SpecialValueHandler::value() const
  92. {
  93. switch (m_result) {
  94. case ResultIsLHS:
  95. return m_lhs;
  96. case ResultIsRHS:
  97. return m_rhs;
  98. case ResultIsUnknown:
  99. default:
  100. ASSERT_NOT_REACHED();
  101. return m_lhs;
  102. }
  103. }
  104. // This class is used for 128 bit unsigned integer arithmetic.
  105. class UInt128 {
  106. public:
  107. UInt128(uint64_t low, uint64_t high)
  108. : m_high(high), m_low(low)
  109. {
  110. }
  111. UInt128& operator/=(uint32_t);
  112. uint64_t high() const { return m_high; }
  113. uint64_t low() const { return m_low; }
  114. static UInt128 multiply(uint64_t u, uint64_t v) { return UInt128(u * v, multiplyHigh(u, v)); }
  115. private:
  116. static uint32_t highUInt32(uint64_t x) { return static_cast<uint32_t>(x >> 32); }
  117. static uint32_t lowUInt32(uint64_t x) { return static_cast<uint32_t>(x & ((static_cast<uint64_t>(1) << 32) - 1)); }
  118. static uint64_t makeUInt64(uint32_t low, uint32_t high) { return low | (static_cast<uint64_t>(high) << 32); }
  119. static uint64_t multiplyHigh(uint64_t, uint64_t);
  120. uint64_t m_high;
  121. uint64_t m_low;
  122. };
  123. UInt128& UInt128::operator/=(const uint32_t divisor)
  124. {
  125. ASSERT(divisor);
  126. if (!m_high) {
  127. m_low /= divisor;
  128. return *this;
  129. }
  130. uint32_t dividend[4];
  131. dividend[0] = lowUInt32(m_low);
  132. dividend[1] = highUInt32(m_low);
  133. dividend[2] = lowUInt32(m_high);
  134. dividend[3] = highUInt32(m_high);
  135. uint32_t quotient[4];
  136. uint32_t remainder = 0;
  137. for (int i = 3; i >= 0; --i) {
  138. const uint64_t work = makeUInt64(dividend[i], remainder);
  139. remainder = static_cast<uint32_t>(work % divisor);
  140. quotient[i] = static_cast<uint32_t>(work / divisor);
  141. }
  142. m_low = makeUInt64(quotient[0], quotient[1]);
  143. m_high = makeUInt64(quotient[2], quotient[3]);
  144. return *this;
  145. }
  146. // Returns high 64bit of 128bit product.
  147. uint64_t UInt128::multiplyHigh(uint64_t u, uint64_t v)
  148. {
  149. const uint64_t uLow = lowUInt32(u);
  150. const uint64_t uHigh = highUInt32(u);
  151. const uint64_t vLow = lowUInt32(v);
  152. const uint64_t vHigh = highUInt32(v);
  153. const uint64_t partialProduct = uHigh * vLow + highUInt32(uLow * vLow);
  154. return uHigh * vHigh + highUInt32(partialProduct) + highUInt32(uLow * vHigh + lowUInt32(partialProduct));
  155. }
  156. static int countDigits(uint64_t x)
  157. {
  158. int numberOfDigits = 0;
  159. for (uint64_t powerOfTen = 1; x >= powerOfTen; powerOfTen *= 10) {
  160. ++numberOfDigits;
  161. if (powerOfTen >= std::numeric_limits<uint64_t>::max() / 10)
  162. break;
  163. }
  164. return numberOfDigits;
  165. }
  166. static uint64_t scaleDown(uint64_t x, int n)
  167. {
  168. ASSERT(n >= 0);
  169. while (n > 0 && x) {
  170. x /= 10;
  171. --n;
  172. }
  173. return x;
  174. }
  175. static uint64_t scaleUp(uint64_t x, int n)
  176. {
  177. ASSERT(n >= 0);
  178. ASSERT(n <= Precision);
  179. uint64_t y = 1;
  180. uint64_t z = 10;
  181. for (;;) {
  182. if (n & 1)
  183. y = y * z;
  184. n >>= 1;
  185. if (!n)
  186. return x * y;
  187. z = z * z;
  188. }
  189. }
  190. } // namespace DecimalPrivate
  191. using namespace DecimalPrivate;
  192. Decimal::EncodedData::EncodedData(Sign sign, FormatClass formatClass)
  193. : m_coefficient(0)
  194. , m_exponent(0)
  195. , m_formatClass(formatClass)
  196. , m_sign(sign)
  197. {
  198. }
  199. Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient)
  200. : m_formatClass(coefficient ? ClassNormal : ClassZero)
  201. , m_sign(sign)
  202. {
  203. if (exponent >= ExponentMin && exponent <= ExponentMax) {
  204. while (coefficient > MaxCoefficient) {
  205. coefficient /= 10;
  206. ++exponent;
  207. }
  208. }
  209. if (exponent > ExponentMax) {
  210. m_coefficient = 0;
  211. m_exponent = 0;
  212. m_formatClass = ClassInfinity;
  213. return;
  214. }
  215. if (exponent < ExponentMin) {
  216. m_coefficient = 0;
  217. m_exponent = 0;
  218. m_formatClass = ClassZero;
  219. return;
  220. }
  221. m_coefficient = coefficient;
  222. m_exponent = static_cast<int16_t>(exponent);
  223. }
  224. bool Decimal::EncodedData::operator==(const EncodedData& another) const
  225. {
  226. return m_sign == another.m_sign
  227. && m_formatClass == another.m_formatClass
  228. && m_exponent == another.m_exponent
  229. && m_coefficient == another.m_coefficient;
  230. }
  231. Decimal::Decimal(int32_t i32)
  232. : m_data(i32 < 0 ? Negative : Positive, 0, i32 < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32)) : static_cast<uint64_t>(i32))
  233. {
  234. }
  235. Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient)
  236. : m_data(sign, coefficient ? exponent : 0, coefficient)
  237. {
  238. }
  239. Decimal::Decimal(const EncodedData& data)
  240. : m_data(data)
  241. {
  242. }
  243. Decimal::Decimal(const Decimal& other)
  244. : m_data(other.m_data)
  245. {
  246. }
  247. Decimal& Decimal::operator=(const Decimal& other)
  248. {
  249. m_data = other.m_data;
  250. return *this;
  251. }
  252. Decimal& Decimal::operator+=(const Decimal& other)
  253. {
  254. m_data = (*this + other).m_data;
  255. return *this;
  256. }
  257. Decimal& Decimal::operator-=(const Decimal& other)
  258. {
  259. m_data = (*this - other).m_data;
  260. return *this;
  261. }
  262. Decimal& Decimal::operator*=(const Decimal& other)
  263. {
  264. m_data = (*this * other).m_data;
  265. return *this;
  266. }
  267. Decimal& Decimal::operator/=(const Decimal& other)
  268. {
  269. m_data = (*this / other).m_data;
  270. return *this;
  271. }
  272. Decimal Decimal::operator-() const
  273. {
  274. if (isNaN())
  275. return *this;
  276. Decimal result(*this);
  277. result.m_data.setSign(invertSign(m_data.sign()));
  278. return result;
  279. }
  280. Decimal Decimal::operator+(const Decimal& rhs) const
  281. {
  282. const Decimal& lhs = *this;
  283. const Sign lhsSign = lhs.sign();
  284. const Sign rhsSign = rhs.sign();
  285. SpecialValueHandler handler(lhs, rhs);
  286. switch (handler.handle()) {
  287. case SpecialValueHandler::BothFinite:
  288. break;
  289. case SpecialValueHandler::BothInfinity:
  290. return lhsSign == rhsSign ? lhs : nan();
  291. case SpecialValueHandler::EitherNaN:
  292. return handler.value();
  293. case SpecialValueHandler::LHSIsInfinity:
  294. return lhs;
  295. case SpecialValueHandler::RHSIsInfinity:
  296. return rhs;
  297. }
  298. const AlignedOperands alignedOperands = alignOperands(lhs, rhs);
  299. const uint64_t result = lhsSign == rhsSign
  300. ? alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient
  301. : alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient;
  302. if (lhsSign == Negative && rhsSign == Positive && !result)
  303. return Decimal(Positive, alignedOperands.exponent, 0);
  304. return static_cast<int64_t>(result) >= 0
  305. ? Decimal(lhsSign, alignedOperands.exponent, result)
  306. : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result));
  307. }
  308. Decimal Decimal::operator-(const Decimal& rhs) const
  309. {
  310. const Decimal& lhs = *this;
  311. const Sign lhsSign = lhs.sign();
  312. const Sign rhsSign = rhs.sign();
  313. SpecialValueHandler handler(lhs, rhs);
  314. switch (handler.handle()) {
  315. case SpecialValueHandler::BothFinite:
  316. break;
  317. case SpecialValueHandler::BothInfinity:
  318. return lhsSign == rhsSign ? nan() : lhs;
  319. case SpecialValueHandler::EitherNaN:
  320. return handler.value();
  321. case SpecialValueHandler::LHSIsInfinity:
  322. return lhs;
  323. case SpecialValueHandler::RHSIsInfinity:
  324. return infinity(invertSign(rhsSign));
  325. }
  326. const AlignedOperands alignedOperands = alignOperands(lhs, rhs);
  327. const uint64_t result = lhsSign == rhsSign
  328. ? alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient
  329. : alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient;
  330. if (lhsSign == Negative && rhsSign == Negative && !result)
  331. return Decimal(Positive, alignedOperands.exponent, 0);
  332. return static_cast<int64_t>(result) >= 0
  333. ? Decimal(lhsSign, alignedOperands.exponent, result)
  334. : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result));
  335. }
  336. Decimal Decimal::operator*(const Decimal& rhs) const
  337. {
  338. const Decimal& lhs = *this;
  339. const Sign lhsSign = lhs.sign();
  340. const Sign rhsSign = rhs.sign();
  341. const Sign resultSign = lhsSign == rhsSign ? Positive : Negative;
  342. SpecialValueHandler handler(lhs, rhs);
  343. switch (handler.handle()) {
  344. case SpecialValueHandler::BothFinite: {
  345. const uint64_t lhsCoefficient = lhs.m_data.coefficient();
  346. const uint64_t rhsCoefficient = rhs.m_data.coefficient();
  347. int resultExponent = lhs.exponent() + rhs.exponent();
  348. UInt128 work(UInt128::multiply(lhsCoefficient, rhsCoefficient));
  349. while (work.high()) {
  350. work /= 10;
  351. ++resultExponent;
  352. }
  353. return Decimal(resultSign, resultExponent, work.low());
  354. }
  355. case SpecialValueHandler::BothInfinity:
  356. return infinity(resultSign);
  357. case SpecialValueHandler::EitherNaN:
  358. return handler.value();
  359. case SpecialValueHandler::LHSIsInfinity:
  360. return rhs.isZero() ? nan() : infinity(resultSign);
  361. case SpecialValueHandler::RHSIsInfinity:
  362. return lhs.isZero() ? nan() : infinity(resultSign);
  363. }
  364. ASSERT_NOT_REACHED();
  365. return nan();
  366. }
  367. Decimal Decimal::operator/(const Decimal& rhs) const
  368. {
  369. const Decimal& lhs = *this;
  370. const Sign lhsSign = lhs.sign();
  371. const Sign rhsSign = rhs.sign();
  372. const Sign resultSign = lhsSign == rhsSign ? Positive : Negative;
  373. SpecialValueHandler handler(lhs, rhs);
  374. switch (handler.handle()) {
  375. case SpecialValueHandler::BothFinite:
  376. break;
  377. case SpecialValueHandler::BothInfinity:
  378. return nan();
  379. case SpecialValueHandler::EitherNaN:
  380. return handler.value();
  381. case SpecialValueHandler::LHSIsInfinity:
  382. return infinity(resultSign);
  383. case SpecialValueHandler::RHSIsInfinity:
  384. return zero(resultSign);
  385. }
  386. ASSERT(lhs.isFinite());
  387. ASSERT(rhs.isFinite());
  388. if (rhs.isZero())
  389. return lhs.isZero() ? nan() : infinity(resultSign);
  390. int resultExponent = lhs.exponent() - rhs.exponent();
  391. if (lhs.isZero())
  392. return Decimal(resultSign, resultExponent, 0);
  393. uint64_t remainder = lhs.m_data.coefficient();
  394. const uint64_t divisor = rhs.m_data.coefficient();
  395. uint64_t result = 0;
  396. for (;;) {
  397. while (remainder < divisor && result < MaxCoefficient / 10) {
  398. remainder *= 10;
  399. result *= 10;
  400. --resultExponent;
  401. }
  402. if (remainder < divisor)
  403. break;
  404. uint64_t quotient = remainder / divisor;
  405. if (result > MaxCoefficient - quotient)
  406. break;
  407. result += quotient;
  408. remainder %= divisor;
  409. if (!remainder)
  410. break;
  411. }
  412. if (remainder > divisor / 2)
  413. ++result;
  414. return Decimal(resultSign, resultExponent, result);
  415. }
  416. bool Decimal::operator==(const Decimal& rhs) const
  417. {
  418. if (isNaN() || rhs.isNaN())
  419. return false;
  420. return m_data == rhs.m_data || compareTo(rhs).isZero();
  421. }
  422. bool Decimal::operator!=(const Decimal& rhs) const
  423. {
  424. if (isNaN() || rhs.isNaN())
  425. return true;
  426. if (m_data == rhs.m_data)
  427. return false;
  428. const Decimal result = compareTo(rhs);
  429. if (result.isNaN())
  430. return false;
  431. return !result.isZero();
  432. }
  433. bool Decimal::operator<(const Decimal& rhs) const
  434. {
  435. const Decimal result = compareTo(rhs);
  436. if (result.isNaN())
  437. return false;
  438. return !result.isZero() && result.isNegative();
  439. }
  440. bool Decimal::operator<=(const Decimal& rhs) const
  441. {
  442. if (isNaN() || rhs.isNaN())
  443. return false;
  444. if (m_data == rhs.m_data)
  445. return true;
  446. const Decimal result = compareTo(rhs);
  447. if (result.isNaN())
  448. return false;
  449. return result.isZero() || result.isNegative();
  450. }
  451. bool Decimal::operator>(const Decimal& rhs) const
  452. {
  453. const Decimal result = compareTo(rhs);
  454. if (result.isNaN())
  455. return false;
  456. return !result.isZero() && result.isPositive();
  457. }
  458. bool Decimal::operator>=(const Decimal& rhs) const
  459. {
  460. if (isNaN() || rhs.isNaN())
  461. return false;
  462. if (m_data == rhs.m_data)
  463. return true;
  464. const Decimal result = compareTo(rhs);
  465. if (result.isNaN())
  466. return false;
  467. return result.isZero() || !result.isNegative();
  468. }
  469. Decimal Decimal::abs() const
  470. {
  471. Decimal result(*this);
  472. result.m_data.setSign(Positive);
  473. return result;
  474. }
  475. Decimal::AlignedOperands Decimal::alignOperands(const Decimal& lhs, const Decimal& rhs)
  476. {
  477. ASSERT(lhs.isFinite());
  478. ASSERT(rhs.isFinite());
  479. const int lhsExponent = lhs.exponent();
  480. const int rhsExponent = rhs.exponent();
  481. int exponent = std::min(lhsExponent, rhsExponent);
  482. uint64_t lhsCoefficient = lhs.m_data.coefficient();
  483. uint64_t rhsCoefficient = rhs.m_data.coefficient();
  484. if (lhsExponent > rhsExponent) {
  485. const int numberOfLHSDigits = countDigits(lhsCoefficient);
  486. if (numberOfLHSDigits) {
  487. const int lhsShiftAmount = lhsExponent - rhsExponent;
  488. const int overflow = numberOfLHSDigits + lhsShiftAmount - Precision;
  489. if (overflow <= 0) {
  490. lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount);
  491. } else {
  492. lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount - overflow);
  493. rhsCoefficient = scaleDown(rhsCoefficient, overflow);
  494. exponent += overflow;
  495. }
  496. }
  497. } else if (lhsExponent < rhsExponent) {
  498. const int numberOfRHSDigits = countDigits(rhsCoefficient);
  499. if (numberOfRHSDigits) {
  500. const int rhsShiftAmount = rhsExponent - lhsExponent;
  501. const int overflow = numberOfRHSDigits + rhsShiftAmount - Precision;
  502. if (overflow <= 0) {
  503. rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount);
  504. } else {
  505. rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount - overflow);
  506. lhsCoefficient = scaleDown(lhsCoefficient, overflow);
  507. exponent += overflow;
  508. }
  509. }
  510. }
  511. AlignedOperands alignedOperands;
  512. alignedOperands.exponent = exponent;
  513. alignedOperands.lhsCoefficient = lhsCoefficient;
  514. alignedOperands.rhsCoefficient = rhsCoefficient;
  515. return alignedOperands;
  516. }
  517. static bool isMultiplePowersOfTen(uint64_t coefficient, int n)
  518. {
  519. return !coefficient || !(coefficient % scaleUp(1, n));
  520. }
  521. // Round toward positive infinity.
  522. Decimal Decimal::ceil() const
  523. {
  524. if (isSpecial())
  525. return *this;
  526. if (exponent() >= 0)
  527. return *this;
  528. uint64_t result = m_data.coefficient();
  529. const int numberOfDigits = countDigits(result);
  530. const int numberOfDropDigits = -exponent();
  531. if (numberOfDigits <= numberOfDropDigits)
  532. return isPositive() ? Decimal(1) : zero(Positive);
  533. result = scaleDown(result, numberOfDropDigits);
  534. if (isPositive() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDropDigits))
  535. ++result;
  536. return Decimal(sign(), 0, result);
  537. }
  538. Decimal Decimal::compareTo(const Decimal& rhs) const
  539. {
  540. const Decimal result(*this - rhs);
  541. switch (result.m_data.formatClass()) {
  542. case EncodedData::ClassInfinity:
  543. return result.isNegative() ? Decimal(-1) : Decimal(1);
  544. case EncodedData::ClassNaN:
  545. case EncodedData::ClassNormal:
  546. return result;
  547. case EncodedData::ClassZero:
  548. return zero(Positive);
  549. default:
  550. ASSERT_NOT_REACHED();
  551. return nan();
  552. }
  553. }
  554. // Round toward negative infinity.
  555. Decimal Decimal::floor() const
  556. {
  557. if (isSpecial())
  558. return *this;
  559. if (exponent() >= 0)
  560. return *this;
  561. uint64_t result = m_data.coefficient();
  562. const int numberOfDigits = countDigits(result);
  563. const int numberOfDropDigits = -exponent();
  564. if (numberOfDigits < numberOfDropDigits)
  565. return isPositive() ? zero(Positive) : Decimal(-1);
  566. result = scaleDown(result, numberOfDropDigits);
  567. if (isNegative() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDropDigits))
  568. ++result;
  569. return Decimal(sign(), 0, result);
  570. }
  571. Decimal Decimal::fromDouble(double doubleValue)
  572. {
  573. if (std::isfinite(doubleValue))
  574. return fromString(mozToString(doubleValue));
  575. if (std::isinf(doubleValue))
  576. return infinity(doubleValue < 0 ? Negative : Positive);
  577. return nan();
  578. }
  579. Decimal Decimal::fromString(const String& str)
  580. {
  581. int exponent = 0;
  582. Sign exponentSign = Positive;
  583. int numberOfDigits = 0;
  584. int numberOfDigitsAfterDot = 0;
  585. int numberOfExtraDigits = 0;
  586. Sign sign = Positive;
  587. enum {
  588. StateDigit,
  589. StateDot,
  590. StateDotDigit,
  591. StateE,
  592. StateEDigit,
  593. StateESign,
  594. StateSign,
  595. StateStart,
  596. StateZero,
  597. } state = StateStart;
  598. #define HandleCharAndBreak(expected, nextState) \
  599. if (ch == expected) { \
  600. state = nextState; \
  601. break; \
  602. }
  603. #define HandleTwoCharsAndBreak(expected1, expected2, nextState) \
  604. if (ch == expected1 || ch == expected2) { \
  605. state = nextState; \
  606. break; \
  607. }
  608. uint64_t accumulator = 0;
  609. for (unsigned index = 0; index < str.length(); ++index) {
  610. const int ch = str[index];
  611. switch (state) {
  612. case StateDigit:
  613. if (ch >= '0' && ch <= '9') {
  614. if (numberOfDigits < Precision) {
  615. ++numberOfDigits;
  616. accumulator *= 10;
  617. accumulator += ch - '0';
  618. } else {
  619. ++numberOfExtraDigits;
  620. }
  621. break;
  622. }
  623. HandleCharAndBreak('.', StateDot);
  624. HandleTwoCharsAndBreak('E', 'e', StateE);
  625. return nan();
  626. case StateDot:
  627. case StateDotDigit:
  628. if (ch >= '0' && ch <= '9') {
  629. if (numberOfDigits < Precision) {
  630. ++numberOfDigits;
  631. ++numberOfDigitsAfterDot;
  632. accumulator *= 10;
  633. accumulator += ch - '0';
  634. }
  635. state = StateDotDigit;
  636. break;
  637. }
  638. HandleTwoCharsAndBreak('E', 'e', StateE);
  639. return nan();
  640. case StateE:
  641. if (ch == '+') {
  642. exponentSign = Positive;
  643. state = StateESign;
  644. break;
  645. }
  646. if (ch == '-') {
  647. exponentSign = Negative;
  648. state = StateESign;
  649. break;
  650. }
  651. if (ch >= '0' && ch <= '9') {
  652. exponent = ch - '0';
  653. state = StateEDigit;
  654. break;
  655. }
  656. return nan();
  657. case StateEDigit:
  658. if (ch >= '0' && ch <= '9') {
  659. exponent *= 10;
  660. exponent += ch - '0';
  661. if (exponent > ExponentMax + Precision) {
  662. if (accumulator)
  663. return exponentSign == Negative ? zero(Positive) : infinity(sign);
  664. return zero(sign);
  665. }
  666. state = StateEDigit;
  667. break;
  668. }
  669. return nan();
  670. case StateESign:
  671. if (ch >= '0' && ch <= '9') {
  672. exponent = ch - '0';
  673. state = StateEDigit;
  674. break;
  675. }
  676. return nan();
  677. case StateSign:
  678. if (ch >= '1' && ch <= '9') {
  679. accumulator = ch - '0';
  680. numberOfDigits = 1;
  681. state = StateDigit;
  682. break;
  683. }
  684. HandleCharAndBreak('0', StateZero);
  685. return nan();
  686. case StateStart:
  687. if (ch >= '1' && ch <= '9') {
  688. accumulator = ch - '0';
  689. numberOfDigits = 1;
  690. state = StateDigit;
  691. break;
  692. }
  693. if (ch == '-') {
  694. sign = Negative;
  695. state = StateSign;
  696. break;
  697. }
  698. if (ch == '+') {
  699. sign = Positive;
  700. state = StateSign;
  701. break;
  702. }
  703. HandleCharAndBreak('0', StateZero);
  704. HandleCharAndBreak('.', StateDot);
  705. return nan();
  706. case StateZero:
  707. if (ch == '0')
  708. break;
  709. if (ch >= '1' && ch <= '9') {
  710. accumulator = ch - '0';
  711. numberOfDigits = 1;
  712. state = StateDigit;
  713. break;
  714. }
  715. HandleCharAndBreak('.', StateDot);
  716. HandleTwoCharsAndBreak('E', 'e', StateE);
  717. return nan();
  718. default:
  719. ASSERT_NOT_REACHED();
  720. return nan();
  721. }
  722. }
  723. if (state == StateZero)
  724. return zero(sign);
  725. if (state == StateDigit || state == StateEDigit || state == StateDotDigit) {
  726. int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits;
  727. if (resultExponent < ExponentMin)
  728. return zero(Positive);
  729. const int overflow = resultExponent - ExponentMax + 1;
  730. if (overflow > 0) {
  731. if (overflow + numberOfDigits - numberOfDigitsAfterDot > Precision)
  732. return infinity(sign);
  733. accumulator = scaleUp(accumulator, overflow);
  734. resultExponent -= overflow;
  735. }
  736. return Decimal(sign, resultExponent, accumulator);
  737. }
  738. return nan();
  739. }
  740. Decimal Decimal::infinity(const Sign sign)
  741. {
  742. return Decimal(EncodedData(sign, EncodedData::ClassInfinity));
  743. }
  744. Decimal Decimal::nan()
  745. {
  746. return Decimal(EncodedData(Positive, EncodedData::ClassNaN));
  747. }
  748. Decimal Decimal::remainder(const Decimal& rhs) const
  749. {
  750. const Decimal quotient = *this / rhs;
  751. return quotient.isSpecial() ? quotient : *this - (quotient.isNegative() ? quotient.ceil() : quotient.floor()) * rhs;
  752. }
  753. Decimal Decimal::round() const
  754. {
  755. if (isSpecial())
  756. return *this;
  757. if (exponent() >= 0)
  758. return *this;
  759. uint64_t result = m_data.coefficient();
  760. const int numberOfDigits = countDigits(result);
  761. const int numberOfDropDigits = -exponent();
  762. if (numberOfDigits < numberOfDropDigits)
  763. return zero(Positive);
  764. result = scaleDown(result, numberOfDropDigits - 1);
  765. if (result % 10 >= 5)
  766. result += 10;
  767. result /= 10;
  768. return Decimal(sign(), 0, result);
  769. }
  770. double Decimal::toDouble() const
  771. {
  772. if (isFinite()) {
  773. bool valid;
  774. const double doubleValue = mozToDouble(toString(), &valid);
  775. return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN();
  776. }
  777. if (isInfinity())
  778. return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
  779. return std::numeric_limits<double>::quiet_NaN();
  780. }
  781. String Decimal::toString() const
  782. {
  783. switch (m_data.formatClass()) {
  784. case EncodedData::ClassInfinity:
  785. return sign() ? "-Infinity" : "Infinity";
  786. case EncodedData::ClassNaN:
  787. return "NaN";
  788. case EncodedData::ClassNormal:
  789. case EncodedData::ClassZero:
  790. break;
  791. default:
  792. ASSERT_NOT_REACHED();
  793. return "";
  794. }
  795. StringBuilder builder;
  796. if (sign())
  797. builder.append('-');
  798. int originalExponent = exponent();
  799. uint64_t coefficient = m_data.coefficient();
  800. if (originalExponent < 0) {
  801. const int maxDigits = DBL_DIG;
  802. uint64_t lastDigit = 0;
  803. while (countDigits(coefficient) > maxDigits) {
  804. lastDigit = coefficient % 10;
  805. coefficient /= 10;
  806. ++originalExponent;
  807. }
  808. if (lastDigit >= 5)
  809. ++coefficient;
  810. while (originalExponent < 0 && coefficient && !(coefficient % 10)) {
  811. coefficient /= 10;
  812. ++originalExponent;
  813. }
  814. }
  815. const String digits = mozToString(coefficient);
  816. int coefficientLength = static_cast<int>(digits.length());
  817. const int adjustedExponent = originalExponent + coefficientLength - 1;
  818. if (originalExponent <= 0 && adjustedExponent >= -6) {
  819. if (!originalExponent) {
  820. builder.append(digits);
  821. return builder.toString();
  822. }
  823. if (adjustedExponent >= 0) {
  824. for (int i = 0; i < coefficientLength; ++i) {
  825. builder.append(digits[i]);
  826. if (i == adjustedExponent)
  827. builder.append('.');
  828. }
  829. return builder.toString();
  830. }
  831. builder.appendLiteral("0.");
  832. for (int i = adjustedExponent + 1; i < 0; ++i)
  833. builder.append('0');
  834. builder.append(digits);
  835. } else {
  836. builder.append(digits[0]);
  837. while (coefficientLength >= 2 && digits[coefficientLength - 1] == '0')
  838. --coefficientLength;
  839. if (coefficientLength >= 2) {
  840. builder.append('.');
  841. for (int i = 1; i < coefficientLength; ++i)
  842. builder.append(digits[i]);
  843. }
  844. if (adjustedExponent) {
  845. builder.append(adjustedExponent < 0 ? "e" : "e+");
  846. builder.appendNumber(adjustedExponent);
  847. }
  848. }
  849. return builder.toString();
  850. }
  851. bool Decimal::toString(char* strBuf, size_t bufLength) const
  852. {
  853. ASSERT(bufLength > 0);
  854. String str = toString();
  855. size_t length = str.copy(strBuf, bufLength);
  856. if (length < bufLength) {
  857. strBuf[length] = '\0';
  858. return true;
  859. }
  860. strBuf[bufLength - 1] = '\0';
  861. return false;
  862. }
  863. Decimal Decimal::zero(Sign sign)
  864. {
  865. return Decimal(EncodedData(sign, EncodedData::ClassZero));
  866. }
  867. } // namespace blink