2
* Copyright (C) 2010 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
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.
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.
27
#include "DecimalNumber.h"
29
#include <wtf/MathExtras.h>
30
#include <wtf/text/WTFString.h>
34
unsigned DecimalNumber::bufferLengthForStringDecimal() const
37
// if the exponent is negative the number decimal representation is of the form:
38
// [<sign>]0.[<zeros>]<significand>
42
length += 2; // for "0."
43
length += -m_exponent - 1;
44
length += m_precision;
48
unsigned digitsBeforeDecimalPoint = m_exponent + 1;
50
// If the precision is <= than the number of digits to get up to the decimal
51
// point, then there is no fractional part, number is of the form:
52
// [<sign>]<significand>[<zeros>]
53
if (m_precision <= digitsBeforeDecimalPoint) {
56
length += m_precision;
57
length += digitsBeforeDecimalPoint - m_precision;
61
// If we get here, number starts before the decimal point, and ends after it,
62
// as such is of the form:
63
// [<sign>]<significand-begin>.<significand-end>
66
length += digitsBeforeDecimalPoint;
67
++length; // for decimal point
68
length += m_precision - digitsBeforeDecimalPoint;
73
unsigned DecimalNumber::bufferLengthForStringExponential() const
79
// Add the significand
82
if (m_precision > 1) {
83
++length; // for decimal point
84
length += m_precision - 1;
90
int exponent = (m_exponent >= 0) ? m_exponent : -m_exponent;
102
unsigned DecimalNumber::toStringDecimal(LChar* buffer, unsigned bufferLength) const
104
ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringDecimal());
106
// Should always be at least one digit to add to the string!
108
LChar* next = buffer;
110
// if the exponent is negative the number decimal representation is of the form:
111
// [<sign>]0.[<zeros>]<significand>
112
if (m_exponent < 0) {
113
unsigned zeros = -m_exponent - 1;
119
for (unsigned i = 0; i < zeros; ++i)
121
for (unsigned i = 0; i < m_precision; ++i)
122
*next++ = m_significand[i];
124
return next - buffer;
127
unsigned digitsBeforeDecimalPoint = m_exponent + 1;
129
// If the precision is <= than the number of digits to get up to the decimal
130
// point, then there is no fractional part, number is of the form:
131
// [<sign>]<significand>[<zeros>]
132
if (m_precision <= digitsBeforeDecimalPoint) {
135
for (unsigned i = 0; i < m_precision; ++i)
136
*next++ = m_significand[i];
137
for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i)
140
return next - buffer;
143
// If we get here, number starts before the decimal point, and ends after it,
144
// as such is of the form:
145
// [<sign>]<significand-begin>.<significand-end>
149
for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i)
150
*next++ = m_significand[i];
152
for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i)
153
*next++ = m_significand[i];
155
return next - buffer;
158
unsigned DecimalNumber::toStringExponential(LChar* buffer, unsigned bufferLength) const
160
ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringExponential());
162
// Should always be at least one digit to add to the string!
164
LChar* next = buffer;
170
// Add the significand
171
*next++ = m_significand[0];
172
if (m_precision > 1) {
174
for (unsigned i = 1; i < m_precision; ++i)
175
*next++ = m_significand[i];
181
if (m_exponent >= 0) {
183
exponent = m_exponent;
186
exponent = -m_exponent;
191
*next++ = '0' + exponent / 100;
193
*next++ = '0' + (exponent % 100) / 10;
194
*next++ = '0' + exponent % 10;
196
return next - buffer;