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