• 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 #include "config.h"
27 #include "DecimalNumber.h"
28 
29 namespace WTF {
30 
bufferLengthForStringDecimal() const31 unsigned DecimalNumber::bufferLengthForStringDecimal() const
32 {
33     unsigned length = 0;
34     // if the exponent is negative the number decimal representation is of the form:
35     // [<sign>]0.[<zeros>]<significand>
36     if (m_exponent < 0) {
37         if (m_sign)
38             ++length;
39         length += 2; // for "0."
40         length += -m_exponent - 1;
41         length += m_precision;
42         return length;
43     }
44 
45     unsigned digitsBeforeDecimalPoint = m_exponent + 1;
46 
47     // If the precision is <= than the number of digits to get up to the decimal
48     // point, then there is no fractional part, number is of the form:
49     // [<sign>]<significand>[<zeros>]
50     if (m_precision <= digitsBeforeDecimalPoint) {
51         if (m_sign)
52             ++length;
53         length += m_precision;
54         length += digitsBeforeDecimalPoint - m_precision;
55         return length;
56     }
57 
58     // If we get here, number starts before the decimal point, and ends after it,
59     // as such is of the form:
60     // [<sign>]<significand-begin>.<significand-end>
61     if (m_sign)
62         ++length;
63     length += digitsBeforeDecimalPoint;
64     ++length; // for decimal point
65     length += m_precision - digitsBeforeDecimalPoint;
66 
67     return length;
68 }
69 
bufferLengthForStringExponential() const70 unsigned DecimalNumber::bufferLengthForStringExponential() const
71 {
72     unsigned length = 0;
73     if (m_sign)
74         ++length;
75 
76     // Add the significand
77     ++length;
78 
79     if (m_precision > 1) {
80         ++length; // for decimal point
81         length += m_precision - 1;
82     }
83 
84     // Add "e+" or "e-"
85     length += 2;
86 
87     int exponent = (m_exponent >= 0) ? m_exponent : -m_exponent;
88 
89     // Add the exponent
90     if (exponent >= 100)
91         ++length;
92     if (exponent >= 10)
93         ++length;
94     ++length;
95 
96     return length;
97 }
98 
toStringDecimal(LChar * buffer,unsigned bufferLength) const99 unsigned DecimalNumber::toStringDecimal(LChar* buffer, unsigned bufferLength) const
100 {
101     ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringDecimal());
102 
103     // Should always be at least one digit to add to the string!
104     ASSERT(m_precision);
105     LChar* next = buffer;
106 
107     // if the exponent is negative the number decimal representation is of the form:
108     // [<sign>]0.[<zeros>]<significand>
109     if (m_exponent < 0) {
110         unsigned zeros = -m_exponent - 1;
111 
112         if (m_sign)
113             *next++ = '-';
114         *next++ = '0';
115         *next++ = '.';
116         for (unsigned i = 0; i < zeros; ++i)
117             *next++ = '0';
118         for (unsigned i = 0; i < m_precision; ++i)
119             *next++ = m_significand[i];
120 
121         return next - buffer;
122     }
123 
124     unsigned digitsBeforeDecimalPoint = m_exponent + 1;
125 
126     // If the precision is <= than the number of digits to get up to the decimal
127     // point, then there is no fractional part, number is of the form:
128     // [<sign>]<significand>[<zeros>]
129     if (m_precision <= digitsBeforeDecimalPoint) {
130         if (m_sign)
131             *next++ = '-';
132         for (unsigned i = 0; i < m_precision; ++i)
133             *next++ = m_significand[i];
134         for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i)
135             *next++ = '0';
136 
137         return next - buffer;
138     }
139 
140     // If we get here, number starts before the decimal point, and ends after it,
141     // as such is of the form:
142     // [<sign>]<significand-begin>.<significand-end>
143 
144     if (m_sign)
145         *next++ = '-';
146     for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i)
147         *next++ = m_significand[i];
148     *next++ = '.';
149     for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i)
150         *next++ = m_significand[i];
151 
152     return next - buffer;
153 }
154 
toStringExponential(LChar * buffer,unsigned bufferLength) const155 unsigned DecimalNumber::toStringExponential(LChar* buffer, unsigned bufferLength) const
156 {
157     ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringExponential());
158 
159     // Should always be at least one digit to add to the string!
160     ASSERT(m_precision);
161     LChar* next = buffer;
162 
163     // Add the sign
164     if (m_sign)
165         *next++ = '-';
166 
167     // Add the significand
168     *next++ = m_significand[0];
169     if (m_precision > 1) {
170         *next++ = '.';
171         for (unsigned i = 1; i < m_precision; ++i)
172             *next++ = m_significand[i];
173     }
174 
175     // Add "e+" or "e-"
176     *next++ = 'e';
177     int exponent;
178     if (m_exponent >= 0) {
179         *next++ = '+';
180         exponent = m_exponent;
181     } else {
182         *next++ = '-';
183         exponent = -m_exponent;
184     }
185 
186     // Add the exponent
187     if (exponent >= 100)
188         *next++ = '0' + exponent / 100;
189     if (exponent >= 10)
190         *next++ = '0' + (exponent % 100) / 10;
191     *next++ = '0' + exponent % 10;
192 
193     return next - buffer;
194 }
195 
196 } // namespace WTF
197