OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/double_conversion.h" | 5 #include "vm/double_conversion.h" |
6 | 6 |
7 #include "third_party/double-conversion/src/double-conversion.h" | 7 #include "third_party/double-conversion/src/double-conversion.h" |
8 | 8 |
9 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
10 #include "vm/globals.h" | 10 #include "vm/globals.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 // 17 digits (the precision needed for doubles), plus the \0. | 27 // 17 digits (the precision needed for doubles), plus the \0. |
28 ASSERT(buffer_size >= 1 + 1 + 1 + kDecimalLow + 17 + 1); | 28 ASSERT(buffer_size >= 1 + 1 + 1 + kDecimalLow + 17 + 1); |
29 // Alternatively it contains a sign, at most 17 digits (precision needed for | 29 // Alternatively it contains a sign, at most 17 digits (precision needed for |
30 // any double), the decimal point, the exponent character, the exponent's | 30 // any double), the decimal point, the exponent character, the exponent's |
31 // sign, at most three exponent digits, plus the \0. | 31 // sign, at most three exponent digits, plus the \0. |
32 ASSERT(buffer_size >= 1 + 17 + 1 + 1 + 1 + 3 + 1); | 32 ASSERT(buffer_size >= 1 + 17 + 1 + 1 + 1 + 3 + 1); |
33 | 33 |
34 static const int kConversionFlags = | 34 static const int kConversionFlags = |
35 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN | | 35 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN | |
36 double_conversion::DoubleToStringConverter::EMIT_TRAILING_DECIMAL_POINT | | 36 double_conversion::DoubleToStringConverter::EMIT_TRAILING_DECIMAL_POINT | |
37 double_conversion::DoubleToStringConverter::EMIT_TRAILING_ZERO_AFTER_POINT; | 37 double_conversion::DoubleToStringConverter:: |
| 38 EMIT_TRAILING_ZERO_AFTER_POINT; |
38 | 39 |
39 const double_conversion::DoubleToStringConverter converter( | 40 const double_conversion::DoubleToStringConverter converter( |
40 kConversionFlags, | 41 kConversionFlags, kDoubleToStringCommonInfinitySymbol, |
41 kDoubleToStringCommonInfinitySymbol, | 42 kDoubleToStringCommonNaNSymbol, kDoubleToStringCommonExponentChar, |
42 kDoubleToStringCommonNaNSymbol, | 43 kDecimalLow, kDecimalHigh, 0, |
43 kDoubleToStringCommonExponentChar, | 44 0); // Last two values are ignored in shortest mode. |
44 kDecimalLow, | |
45 kDecimalHigh, | |
46 0, 0); // Last two values are ignored in shortest mode. | |
47 | 45 |
48 double_conversion::StringBuilder builder(buffer, buffer_size); | 46 double_conversion::StringBuilder builder(buffer, buffer_size); |
49 bool status = converter.ToShortest(d, &builder); | 47 bool status = converter.ToShortest(d, &builder); |
50 ASSERT(status); | 48 ASSERT(status); |
51 char* result = builder.Finalize(); | 49 char* result = builder.Finalize(); |
52 ASSERT(result == buffer); | 50 ASSERT(result == buffer); |
53 } | 51 } |
54 | 52 |
55 RawString* DoubleToStringAsFixed(double d, int fraction_digits) { | 53 RawString* DoubleToStringAsFixed(double d, int fraction_digits) { |
56 static const int kMinFractionDigits = 0; | 54 static const int kMinFractionDigits = 0; |
(...skipping 16 matching lines...) Expand all Loading... |
73 // The output contains the sign, at most kMaxDigitsBeforePoint digits, | 71 // The output contains the sign, at most kMaxDigitsBeforePoint digits, |
74 // the decimal point followed by at most fraction_digits digits plus the \0. | 72 // the decimal point followed by at most fraction_digits digits plus the \0. |
75 ASSERT(kBufferSize >= 1 + kMaxDigitsBeforePoint + 1 + kMaxFractionDigits + 1); | 73 ASSERT(kBufferSize >= 1 + kMaxDigitsBeforePoint + 1 + kMaxFractionDigits + 1); |
76 | 74 |
77 ASSERT(kLowerBoundary < d && d < kUpperBoundary); | 75 ASSERT(kLowerBoundary < d && d < kUpperBoundary); |
78 | 76 |
79 ASSERT(kMinFractionDigits <= fraction_digits && | 77 ASSERT(kMinFractionDigits <= fraction_digits && |
80 fraction_digits <= kMaxFractionDigits); | 78 fraction_digits <= kMaxFractionDigits); |
81 | 79 |
82 const double_conversion::DoubleToStringConverter converter( | 80 const double_conversion::DoubleToStringConverter converter( |
83 kConversionFlags, | 81 kConversionFlags, kDoubleToStringCommonInfinitySymbol, |
84 kDoubleToStringCommonInfinitySymbol, | 82 kDoubleToStringCommonNaNSymbol, kDoubleToStringCommonExponentChar, 0, 0, |
85 kDoubleToStringCommonNaNSymbol, | 83 0, 0); // Last four values are ignored in fixed mode. |
86 kDoubleToStringCommonExponentChar, | |
87 0, 0, 0, 0); // Last four values are ignored in fixed mode. | |
88 | 84 |
89 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); | 85 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); |
90 buffer[kBufferSize - 1] = '\0'; | 86 buffer[kBufferSize - 1] = '\0'; |
91 double_conversion::StringBuilder builder(buffer, kBufferSize); | 87 double_conversion::StringBuilder builder(buffer, kBufferSize); |
92 bool status = converter.ToFixed(d, fraction_digits, &builder); | 88 bool status = converter.ToFixed(d, fraction_digits, &builder); |
93 ASSERT(status); | 89 ASSERT(status); |
94 return String::New(builder.Finalize()); | 90 return String::New(builder.Finalize()); |
95 } | 91 } |
96 | 92 |
97 | 93 |
98 RawString* DoubleToStringAsExponential(double d, int fraction_digits) { | 94 RawString* DoubleToStringAsExponential(double d, int fraction_digits) { |
99 static const int kMinFractionDigits = -1; // -1 represents shortest mode. | 95 static const int kMinFractionDigits = -1; // -1 represents shortest mode. |
100 static const int kMaxFractionDigits = 20; | 96 static const int kMaxFractionDigits = 20; |
101 static const int kConversionFlags = | 97 static const int kConversionFlags = |
102 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN; | 98 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN; |
103 const int kBufferSize = 128; | 99 const int kBufferSize = 128; |
104 | 100 |
105 USE(kMinFractionDigits); | 101 USE(kMinFractionDigits); |
106 USE(kMaxFractionDigits); | 102 USE(kMaxFractionDigits); |
107 // The output contains the sign, at most 1 digits, the decimal point followed | 103 // The output contains the sign, at most 1 digits, the decimal point followed |
108 // by at most kMaxFractionDigits digits, the exponent-character, the | 104 // by at most kMaxFractionDigits digits, the exponent-character, the |
109 // exponent-sign and three exponent digits plus \0. | 105 // exponent-sign and three exponent digits plus \0. |
110 ASSERT(kBufferSize >= 1 + 1 + kMaxFractionDigits + 1 + 1 + 3 + 1); | 106 ASSERT(kBufferSize >= 1 + 1 + kMaxFractionDigits + 1 + 1 + 3 + 1); |
111 | 107 |
112 ASSERT(kMinFractionDigits <= fraction_digits && | 108 ASSERT(kMinFractionDigits <= fraction_digits && |
113 fraction_digits <= kMaxFractionDigits); | 109 fraction_digits <= kMaxFractionDigits); |
114 | 110 |
115 const double_conversion::DoubleToStringConverter converter( | 111 const double_conversion::DoubleToStringConverter converter( |
116 kConversionFlags, | 112 kConversionFlags, kDoubleToStringCommonInfinitySymbol, |
117 kDoubleToStringCommonInfinitySymbol, | 113 kDoubleToStringCommonNaNSymbol, kDoubleToStringCommonExponentChar, 0, 0, |
118 kDoubleToStringCommonNaNSymbol, | 114 0, 0); // Last four values are ignored in exponential mode. |
119 kDoubleToStringCommonExponentChar, | |
120 0, 0, 0, 0); // Last four values are ignored in exponential mode. | |
121 | 115 |
122 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); | 116 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); |
123 buffer[kBufferSize - 1] = '\0'; | 117 buffer[kBufferSize - 1] = '\0'; |
124 double_conversion::StringBuilder builder(buffer, kBufferSize); | 118 double_conversion::StringBuilder builder(buffer, kBufferSize); |
125 bool status = converter.ToExponential(d, fraction_digits, &builder); | 119 bool status = converter.ToExponential(d, fraction_digits, &builder); |
126 ASSERT(status); | 120 ASSERT(status); |
127 return String::New(builder.Finalize()); | 121 return String::New(builder.Finalize()); |
128 } | 122 } |
129 | 123 |
130 | 124 |
131 RawString* DoubleToStringAsPrecision(double d, int precision) { | 125 RawString* DoubleToStringAsPrecision(double d, int precision) { |
132 static const int kMinPrecisionDigits = 1; | 126 static const int kMinPrecisionDigits = 1; |
133 static const int kMaxPrecisionDigits = 21; | 127 static const int kMaxPrecisionDigits = 21; |
134 static const int kMaxLeadingPaddingZeroes = 6; | 128 static const int kMaxLeadingPaddingZeroes = 6; |
135 static const int kMaxTrailingPaddingZeroes = 0; | 129 static const int kMaxTrailingPaddingZeroes = 0; |
136 static const int kConversionFlags = | 130 static const int kConversionFlags = |
137 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN; | 131 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN; |
138 const int kBufferSize = 128; | 132 const int kBufferSize = 128; |
139 | 133 |
140 USE(kMinPrecisionDigits); | 134 USE(kMinPrecisionDigits); |
141 USE(kMaxPrecisionDigits); | 135 USE(kMaxPrecisionDigits); |
142 // The output contains the sign, a potential leading 0, the decimal point, | 136 // The output contains the sign, a potential leading 0, the decimal point, |
143 // at most kMax{Leading|Trailing} padding zeroes, precision digits, | 137 // at most kMax{Leading|Trailing} padding zeroes, precision digits, |
144 // the exponent-character, the exponent-sign, three exponent digits | 138 // the exponent-character, the exponent-sign, three exponent digits |
145 // plus the \0. | 139 // plus the \0. |
146 // Note that padding and exponent are exclusive. We still add them up. | 140 // Note that padding and exponent are exclusive. We still add them up. |
147 ASSERT(kBufferSize >= 1 + 1 + 1 + kMaxLeadingPaddingZeroes + | 141 ASSERT(kBufferSize >= 1 + 1 + 1 + kMaxLeadingPaddingZeroes + |
148 kMaxTrailingPaddingZeroes + kMaxPrecisionDigits + 1 + 1 + 3 + 1); | 142 kMaxTrailingPaddingZeroes + kMaxPrecisionDigits + |
| 143 1 + 1 + 3 + 1); |
149 | 144 |
150 ASSERT(kMinPrecisionDigits <= precision && precision <= kMaxPrecisionDigits); | 145 ASSERT(kMinPrecisionDigits <= precision && precision <= kMaxPrecisionDigits); |
151 | 146 |
152 const double_conversion::DoubleToStringConverter converter( | 147 const double_conversion::DoubleToStringConverter converter( |
153 kConversionFlags, | 148 kConversionFlags, kDoubleToStringCommonInfinitySymbol, |
154 kDoubleToStringCommonInfinitySymbol, | 149 kDoubleToStringCommonNaNSymbol, kDoubleToStringCommonExponentChar, 0, |
155 kDoubleToStringCommonNaNSymbol, | 150 0, // Ignored in precision mode. |
156 kDoubleToStringCommonExponentChar, | 151 kMaxLeadingPaddingZeroes, kMaxTrailingPaddingZeroes); |
157 0, 0, // Ignored in precision mode. | |
158 kMaxLeadingPaddingZeroes, | |
159 kMaxTrailingPaddingZeroes); | |
160 | 152 |
161 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); | 153 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); |
162 buffer[kBufferSize - 1] = '\0'; | 154 buffer[kBufferSize - 1] = '\0'; |
163 double_conversion::StringBuilder builder(buffer, kBufferSize); | 155 double_conversion::StringBuilder builder(buffer, kBufferSize); |
164 bool status = converter.ToPrecision(d, precision, &builder); | 156 bool status = converter.ToPrecision(d, precision, &builder); |
165 ASSERT(status); | 157 ASSERT(status); |
166 return String::New(builder.Finalize()); | 158 return String::New(builder.Finalize()); |
167 } | 159 } |
168 | 160 |
169 | 161 |
170 bool CStringToDouble(const char* str, intptr_t length, double* result) { | 162 bool CStringToDouble(const char* str, intptr_t length, double* result) { |
171 if (length == 0) { | 163 if (length == 0) { |
172 return false; | 164 return false; |
173 } | 165 } |
174 | 166 |
175 double_conversion::StringToDoubleConverter converter( | 167 double_conversion::StringToDoubleConverter converter( |
176 double_conversion::StringToDoubleConverter::NO_FLAGS, | 168 double_conversion::StringToDoubleConverter::NO_FLAGS, 0.0, 0.0, |
177 0.0, | 169 kDoubleToStringCommonInfinitySymbol, kDoubleToStringCommonNaNSymbol); |
178 0.0, | |
179 kDoubleToStringCommonInfinitySymbol, | |
180 kDoubleToStringCommonNaNSymbol); | |
181 | 170 |
182 int parsed_count = 0; | 171 int parsed_count = 0; |
183 *result = converter.StringToDouble(str, | 172 *result = |
184 static_cast<int>(length), | 173 converter.StringToDouble(str, static_cast<int>(length), &parsed_count); |
185 &parsed_count); | |
186 return (parsed_count == length); | 174 return (parsed_count == length); |
187 } | 175 } |
188 | 176 |
189 | 177 |
190 } // namespace dart | 178 } // namespace dart |
OLD | NEW |