Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

118 řádky
4.0 KiB

  1. // Copyright 2010 the V8 project authors. All rights reserved.
  2. // Redistribution and use in source and binary forms, with or without
  3. // modification, are permitted provided that the following conditions are
  4. // met:
  5. //
  6. // * Redistributions of source code must retain the above copyright
  7. // notice, this list of conditions and the following disclaimer.
  8. // * Redistributions in binary form must reproduce the above
  9. // copyright notice, this list of conditions and the following
  10. // disclaimer in the documentation and/or other materials provided
  11. // with the distribution.
  12. // * Neither the name of Google Inc. nor the names of its
  13. // contributors may be used to endorse or promote products derived
  14. // from this software without specific prior written permission.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  18. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  19. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  20. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  21. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. #ifndef DOUBLE_CONVERSION_DIY_FP_H_
  28. #define DOUBLE_CONVERSION_DIY_FP_H_
  29. #include "utils.h"
  30. namespace double_conversion {
  31. // This "Do It Yourself Floating Point" class implements a floating-point number
  32. // with a uint64 significand and an int exponent. Normalized DiyFp numbers will
  33. // have the most significant bit of the significand set.
  34. // Multiplication and Subtraction do not normalize their results.
  35. // DiyFp are not designed to contain special doubles (NaN and Infinity).
  36. class DiyFp {
  37. public:
  38. static const int kSignificandSize = 64;
  39. DiyFp() : f_(0), e_(0) {}
  40. DiyFp(uint64_t significand, int exponent) : f_(significand), e_(exponent) {}
  41. // this = this - other.
  42. // The exponents of both numbers must be the same and the significand of this
  43. // must be bigger than the significand of other.
  44. // The result will not be normalized.
  45. void Subtract(const DiyFp& other) {
  46. ASSERT(e_ == other.e_);
  47. ASSERT(f_ >= other.f_);
  48. f_ -= other.f_;
  49. }
  50. // Returns a - b.
  51. // The exponents of both numbers must be the same and this must be bigger
  52. // than other. The result will not be normalized.
  53. static DiyFp Minus(const DiyFp& a, const DiyFp& b) {
  54. DiyFp result = a;
  55. result.Subtract(b);
  56. return result;
  57. }
  58. // this = this * other.
  59. void Multiply(const DiyFp& other);
  60. // returns a * b;
  61. static DiyFp Times(const DiyFp& a, const DiyFp& b) {
  62. DiyFp result = a;
  63. result.Multiply(b);
  64. return result;
  65. }
  66. void Normalize() {
  67. ASSERT(f_ != 0);
  68. uint64_t significand = f_;
  69. int exponent = e_;
  70. // This method is mainly called for normalizing boundaries. In general
  71. // boundaries need to be shifted by 10 bits. We thus optimize for this case.
  72. const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000);
  73. while ((significand & k10MSBits) == 0) {
  74. significand <<= 10;
  75. exponent -= 10;
  76. }
  77. while ((significand & kUint64MSB) == 0) {
  78. significand <<= 1;
  79. exponent--;
  80. }
  81. f_ = significand;
  82. e_ = exponent;
  83. }
  84. static DiyFp Normalize(const DiyFp& a) {
  85. DiyFp result = a;
  86. result.Normalize();
  87. return result;
  88. }
  89. uint64_t f() const { return f_; }
  90. int e() const { return e_; }
  91. void set_f(uint64_t new_value) { f_ = new_value; }
  92. void set_e(int new_value) { e_ = new_value; }
  93. private:
  94. static const uint64_t kUint64MSB = UINT64_2PART_C(0x80000000, 00000000);
  95. uint64_t f_;
  96. int e_;
  97. };
  98. } // namespace double_conversion
  99. #endif // DOUBLE_CONVERSION_DIY_FP_H_