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