DecimalNumber.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright (C) 2010 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 DecimalNumber_h
  26. #define DecimalNumber_h
  27. #include <math.h>
  28. #include <wtf/dtoa.h>
  29. #include <wtf/MathExtras.h>
  30. #include <wtf/text/WTFString.h>
  31. namespace WTF {
  32. enum RoundingSignificantFiguresType { RoundingSignificantFigures };
  33. enum RoundingDecimalPlacesType { RoundingDecimalPlaces };
  34. class DecimalNumber {
  35. public:
  36. DecimalNumber(double d)
  37. {
  38. ASSERT(std::isfinite(d));
  39. dtoa(m_significand, d, m_sign, m_exponent, m_precision);
  40. ASSERT(m_precision);
  41. // Zero should always have exponent 0.
  42. ASSERT(m_significand[0] != '0' || !m_exponent);
  43. // No values other than zero should have a leading zero.
  44. ASSERT(m_significand[0] != '0' || m_precision == 1);
  45. // No values other than zero should have trailing zeros.
  46. ASSERT(m_significand[0] == '0' || m_significand[m_precision - 1] != '0');
  47. }
  48. DecimalNumber(double d, RoundingSignificantFiguresType, unsigned significantFigures)
  49. {
  50. ASSERT(std::isfinite(d));
  51. dtoaRoundSF(m_significand, d, significantFigures, m_sign, m_exponent, m_precision);
  52. ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
  53. while (m_precision < significantFigures)
  54. m_significand[m_precision++] = '0';
  55. ASSERT(m_precision);
  56. // Zero should always have exponent 0.
  57. ASSERT(m_significand[0] != '0' || !m_exponent);
  58. }
  59. DecimalNumber(double d, RoundingDecimalPlacesType, unsigned decimalPlaces)
  60. {
  61. ASSERT(std::isfinite(d));
  62. dtoaRoundDP(m_significand, d, decimalPlaces, m_sign, m_exponent, m_precision);
  63. unsigned significantFigures = 1 + m_exponent + decimalPlaces;
  64. ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
  65. while (m_precision < significantFigures)
  66. m_significand[m_precision++] = '0';
  67. ASSERT(m_precision);
  68. // Zero should always have exponent 0.
  69. ASSERT(m_significand[0] != '0' || !m_exponent);
  70. }
  71. WTF_EXPORT_PRIVATE unsigned bufferLengthForStringDecimal() const;
  72. WTF_EXPORT_PRIVATE unsigned bufferLengthForStringExponential() const;
  73. WTF_EXPORT_PRIVATE unsigned toStringDecimal(LChar* buffer, unsigned bufferLength) const;
  74. WTF_EXPORT_PRIVATE unsigned toStringExponential(LChar* buffer, unsigned bufferLength) const;
  75. bool sign() const { return m_sign; }
  76. int exponent() const { return m_exponent; }
  77. const char* significand() const { return m_significand; } // significand contains precision characters, is not null-terminated.
  78. unsigned precision() const { return m_precision; }
  79. private:
  80. bool m_sign;
  81. int m_exponent;
  82. DtoaBuffer m_significand;
  83. unsigned m_precision;
  84. };
  85. } // namespace WTF
  86. using WTF::DecimalNumber;
  87. using WTF::RoundingSignificantFigures;
  88. using WTF::RoundingDecimalPlaces;
  89. #endif // DecimalNumber_h