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