| 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 |