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

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

Issue 977593004: Avoid uint64_t overflow in Decimal::operator/() and fix Decimal::ceil() (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-03-04T15:05:41 Created 5 years, 9 months 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 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 return lhs.isZero() ? nan() : infinity(resultSign); 481 return lhs.isZero() ? nan() : infinity(resultSign);
482 482
483 int resultExponent = lhs.exponent() - rhs.exponent(); 483 int resultExponent = lhs.exponent() - rhs.exponent();
484 484
485 if (lhs.isZero()) 485 if (lhs.isZero())
486 return Decimal(resultSign, resultExponent, 0); 486 return Decimal(resultSign, resultExponent, 0);
487 487
488 uint64_t remainder = lhs.m_data.coefficient(); 488 uint64_t remainder = lhs.m_data.coefficient();
489 const uint64_t divisor = rhs.m_data.coefficient(); 489 const uint64_t divisor = rhs.m_data.coefficient();
490 uint64_t result = 0; 490 uint64_t result = 0;
491 while (result < MaxCoefficient / 100) { 491 for (;;) {
492 while (remainder < divisor) { 492 while (remainder < divisor && result < MaxCoefficient / 10) {
493 remainder *= 10; 493 remainder *= 10;
494 result *= 10; 494 result *= 10;
495 --resultExponent; 495 --resultExponent;
496 } 496 }
497 result += remainder / divisor; 497 if (remainder < divisor)
498 break;
499 uint64_t quotient = remainder / divisor;
500 if (result > MaxCoefficient - quotient)
501 break;
502 result += quotient;
498 remainder %= divisor; 503 remainder %= divisor;
499 if (!remainder) 504 if (!remainder)
500 break; 505 break;
501 } 506 }
502 507
503 if (remainder > divisor / 2) 508 if (remainder > divisor / 2)
504 ++result; 509 ++result;
505 510
506 return Decimal(resultSign, resultExponent, result); 511 return Decimal(resultSign, resultExponent, result);
507 } 512 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 { 626 {
622 if (isSpecial()) 627 if (isSpecial())
623 return *this; 628 return *this;
624 629
625 if (exponent() >= 0) 630 if (exponent() >= 0)
626 return *this; 631 return *this;
627 632
628 uint64_t result = m_data.coefficient(); 633 uint64_t result = m_data.coefficient();
629 const int numberOfDigits = countDigits(result); 634 const int numberOfDigits = countDigits(result);
630 const int numberOfDropDigits = -exponent(); 635 const int numberOfDropDigits = -exponent();
631 if (numberOfDigits < numberOfDropDigits) 636 if (numberOfDigits <= numberOfDropDigits)
632 return isPositive() ? Decimal(1) : zero(Positive); 637 return isPositive() ? Decimal(1) : zero(Positive);
633 638
634 result = scaleDown(result, numberOfDropDigits); 639 result = scaleDown(result, numberOfDropDigits);
635 if (isPositive() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDro pDigits)) 640 if (isPositive() && !isMultiplePowersOfTen(m_data.coefficient(), numberOfDro pDigits))
636 ++result; 641 ++result;
637 return Decimal(sign(), 0, result); 642 return Decimal(sign(), 0, result);
638 } 643 }
639 644
640 Decimal Decimal::compareTo(const Decimal& rhs) const 645 Decimal Decimal::compareTo(const Decimal& rhs) const
641 { 646 {
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 } 1021 }
1017 return builder.toString(); 1022 return builder.toString();
1018 } 1023 }
1019 1024
1020 Decimal Decimal::zero(Sign sign) 1025 Decimal Decimal::zero(Sign sign)
1021 { 1026 {
1022 return Decimal(EncodedData(sign, EncodedData::ClassZero)); 1027 return Decimal(EncodedData(sign, EncodedData::ClassZero));
1023 } 1028 }
1024 1029
1025 } // namespace blink 1030 } // namespace blink
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