Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: Source/platform/Decimal.cpp

Issue 59603006: Fix Decimal.floor() + Decimal.ceiling() for most non-integral values. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Express integral check via is-power-of-10 predicate instead Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Source/platform/DecimalTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 } 605 }
606 } 606 }
607 607
608 AlignedOperands alignedOperands; 608 AlignedOperands alignedOperands;
609 alignedOperands.exponent = exponent; 609 alignedOperands.exponent = exponent;
610 alignedOperands.lhsCoefficient = lhsCoefficient; 610 alignedOperands.lhsCoefficient = lhsCoefficient;
611 alignedOperands.rhsCoefficient = rhsCoefficient; 611 alignedOperands.rhsCoefficient = rhsCoefficient;
612 return alignedOperands; 612 return alignedOperands;
613 } 613 }
614 614
615 static bool isMultiplePowersOfTen(uint64_t coefficient, int n)
616 {
617 return !coefficient || !(coefficient % scaleUp(1, n));
618 }
619
615 // Round toward positive infinity. 620 // Round toward positive infinity.
616 // Note: Mac ports defines ceil(x) as wtf_ceil(x), so we can't use name "ceil" h ere. 621 // Note: Mac ports defines ceil(x) as wtf_ceil(x), so we can't use name "ceil" h ere.
617 Decimal Decimal::ceiling() const 622 Decimal Decimal::ceiling() const
618 { 623 {
619 if (isSpecial()) 624 if (isSpecial())
620 return *this; 625 return *this;
621 626
622 if (exponent() >= 0) 627 if (exponent() >= 0)
623 return *this; 628 return *this;
624 629
625 uint64_t result = m_data.coefficient(); 630 uint64_t result = m_data.coefficient();
626 const int numberOfDigits = countDigits(result); 631 const int numberOfDigits = countDigits(result);
627 const int numberOfDropDigits = -exponent(); 632 const int numberOfDropDigits = -exponent();
628 if (numberOfDigits < numberOfDropDigits) 633 if (numberOfDigits < numberOfDropDigits)
629 return isPositive() ? Decimal(1) : zero(Positive); 634 return isPositive() ? Decimal(1) : zero(Positive);
630 635
631 result = scaleDown(result, numberOfDropDigits - 1); 636 result = scaleDown(result, numberOfDropDigits);
632 if (sign() == Positive && result % 10 > 0) 637 if (isPositive() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDro pDigits))
633 result += 10; 638 ++result;
634 result /= 10;
635 return Decimal(sign(), 0, result); 639 return Decimal(sign(), 0, result);
636 } 640 }
637 641
638 Decimal Decimal::compareTo(const Decimal& rhs) const 642 Decimal Decimal::compareTo(const Decimal& rhs) const
639 { 643 {
640 const Decimal result(*this - rhs); 644 const Decimal result(*this - rhs);
641 switch (result.m_data.formatClass()) { 645 switch (result.m_data.formatClass()) {
642 case EncodedData::ClassInfinity: 646 case EncodedData::ClassInfinity:
643 return result.isNegative() ? Decimal(-1) : Decimal(1); 647 return result.isNegative() ? Decimal(-1) : Decimal(1);
644 648
(...skipping 18 matching lines...) Expand all
663 667
664 if (exponent() >= 0) 668 if (exponent() >= 0)
665 return *this; 669 return *this;
666 670
667 uint64_t result = m_data.coefficient(); 671 uint64_t result = m_data.coefficient();
668 const int numberOfDigits = countDigits(result); 672 const int numberOfDigits = countDigits(result);
669 const int numberOfDropDigits = -exponent(); 673 const int numberOfDropDigits = -exponent();
670 if (numberOfDigits < numberOfDropDigits) 674 if (numberOfDigits < numberOfDropDigits)
671 return isPositive() ? zero(Positive) : Decimal(-1); 675 return isPositive() ? zero(Positive) : Decimal(-1);
672 676
673 result = scaleDown(result, numberOfDropDigits - 1); 677 result = scaleDown(result, numberOfDropDigits);
674 if (isNegative() && result % 10 > 0) 678 if (isNegative() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDro pDigits))
675 result += 10; 679 ++result;
676 result /= 10;
677 return Decimal(sign(), 0, result); 680 return Decimal(sign(), 0, result);
678 } 681 }
679 682
680 Decimal Decimal::fromDouble(double doubleValue) 683 Decimal Decimal::fromDouble(double doubleValue)
681 { 684 {
682 if (std::isfinite(doubleValue)) 685 if (std::isfinite(doubleValue))
683 return fromString(String::numberToStringECMAScript(doubleValue)); 686 return fromString(String::numberToStringECMAScript(doubleValue));
684 687
685 if (std::isinf(doubleValue)) 688 if (std::isinf(doubleValue))
686 return infinity(doubleValue < 0 ? Negative : Positive); 689 return infinity(doubleValue < 0 ? Negative : Positive);
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 } 1028 }
1026 return builder.toString(); 1029 return builder.toString();
1027 } 1030 }
1028 1031
1029 Decimal Decimal::zero(Sign sign) 1032 Decimal Decimal::zero(Sign sign)
1030 { 1033 {
1031 return Decimal(EncodedData(sign, EncodedData::ClassZero)); 1034 return Decimal(EncodedData(sign, EncodedData::ClassZero));
1032 } 1035 }
1033 1036
1034 } // namespace WebCore 1037 } // namespace WebCore
OLDNEW
« no previous file with comments | « no previous file | Source/platform/DecimalTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698