8278dfe4f6ac7fc923441aeda1ba43424788c4c6
[WebKit-https.git] / Source / WTF / wtf / DecimalNumber.h
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(isfinite(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(isfinite(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(isfinite(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     WTF_EXPORT_PRIVATE unsigned bufferLengthForStringDecimal() const;
85     WTF_EXPORT_PRIVATE unsigned bufferLengthForStringExponential() const;
86
87     WTF_EXPORT_PRIVATE unsigned toStringDecimal(LChar* buffer, unsigned bufferLength) const;
88     WTF_EXPORT_PRIVATE unsigned toStringExponential(LChar* 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