Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: runtime/vm/double_conversion.cc

Issue 9113043: Implement Double.{toString, toStringAsExponential, toStringAsPrecision} (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Revert mintmaker changes. Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "vm/object.h" 11 #include "vm/object.h"
12 12
13 namespace dart { 13 namespace dart {
14 14
15 static const char kDoubleToStringCommonExponentChar = 'e'; 15 static const char kDoubleToStringCommonExponentChar = 'e';
16 static const char* kDoubleToStringCommonInfinitySymbol = "Infinity"; 16 static const char* kDoubleToStringCommonInfinitySymbol = "Infinity";
17 static const char* kDoubleToStringCommonNaNSymbol = "NaN"; 17 static const char* kDoubleToStringCommonNaNSymbol = "NaN";
18 18
19 bool DoubleToString(double d, String& result) { 19 bool DoubleToCString(double d, char* buffer, int buffer_size,
20 int* result_length) {
20 static const int kDecimalLow = -6; 21 static const int kDecimalLow = -6;
21 static const int kDecimalHigh = 21; 22 static const int kDecimalHigh = 21;
23
24 // The output contains the sign, at most kDecimalHigh - 1 digits,
25 // the decimal point followed by a 0 plus the \0.
26 ASSERT(buffer_size >= 1 + (kDecimalHigh - 1) + 1 + 1 + 1);
27 // Or it contains the sign, a 0, the decimal point, kDecimalLow '0's,
28 // 17 digits (the precision needed for doubles), plus the \0.
29 ASSERT(buffer_size >= 1 + 1 + 1 + kDecimalLow + 17 + 1);
30 // Alternatively it contains a sign, at most 17 digits (precision needed for
31 // any double), the decimal point, the exponent character, the exponent's
32 // sign, at most three exponent digits, plus the \0.
33 ASSERT(buffer_size >= 1 + 17 + 1 + 1 + 1 + 3 + 1);
34
22 static const int kConversionFlags = 35 static const int kConversionFlags =
23 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN | 36 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN |
24 double_conversion::DoubleToStringConverter::EMIT_TRAILING_DECIMAL_POINT | 37 double_conversion::DoubleToStringConverter::EMIT_TRAILING_DECIMAL_POINT |
25 double_conversion::DoubleToStringConverter::EMIT_TRAILING_ZERO_AFTER_POINT; 38 double_conversion::DoubleToStringConverter::EMIT_TRAILING_ZERO_AFTER_POINT;
26 const int kBufferSize = 128;
27 // The output contains the sign, at most kDecimalHigh - 1 digits,
28 // the decimal point followed by a 0 plus the \0.
29 ASSERT(kBufferSize >= 1 + (kDecimalHigh - 1) + 1 + 1 + 1);
30 // Or it contains the sign, a 0, the decimal point, kDecimalLow '0's,
31 // 17 digits (the precision needed for doubles), plus the \0.
32 ASSERT(kBufferSize >= 1 + 1 + 1 + kDecimalLow + 17 + 1);
33 // Alternatively it contains a sign, at most 17 digits (precision needed for
34 // any double), the decimal point, the exponent character, the exponent's
35 // sign, at most three exponent digits, plus the \0.
36 ASSERT(kBufferSize >= 1 + 17 + 1 + 1 + 1 + 3 + 1);
37 39
38 const double_conversion::DoubleToStringConverter converter( 40 const double_conversion::DoubleToStringConverter converter(
39 kConversionFlags, 41 kConversionFlags,
40 kDoubleToStringCommonInfinitySymbol, 42 kDoubleToStringCommonInfinitySymbol,
41 kDoubleToStringCommonNaNSymbol, 43 kDoubleToStringCommonNaNSymbol,
42 kDoubleToStringCommonExponentChar, 44 kDoubleToStringCommonExponentChar,
43 kDecimalLow, 45 kDecimalLow,
44 kDecimalHigh, 46 kDecimalHigh,
45 0, 0); // Last two values are ignored in shortest mode. 47 0, 0); // Last two values are ignored in shortest mode.
46 48
47 UNIMPLEMENTED(); 49 double_conversion::StringBuilder builder(buffer, buffer_size);
48 return false; 50 bool status = converter.ToShortest(d, &builder);
51 if (!status) return false;
52 *result_length = builder.position() + 1; // Include trailing \0 character.
53 char* result = builder.Finalize();
54 ASSERT(result == buffer);
55 return true;
56 }
57
58 bool DoubleToString(double d, String& result) {
59 const int kBufferSize = 128;
60 char buffer[kBufferSize];
61 int length;
62 bool status = DoubleToCString(d, buffer, kBufferSize, &length);
63 if (!status) return false;
64 result ^= String::New(reinterpret_cast<uint8_t*>(buffer), length);
65 return true;
49 } 66 }
50 67
51 bool DoubleToStringAsFixed(double d, int fraction_digits, String& result) { 68 bool DoubleToStringAsFixed(double d, int fraction_digits, String& result) {
52 static const int kMinFractionDigits = 0; 69 static const int kMinFractionDigits = 0;
53 static const int kMaxFractionDigits = 20; 70 static const int kMaxFractionDigits = 20;
54 static const int kMaxDigitsBeforePoint = 20; 71 static const int kMaxDigitsBeforePoint = 20;
55 // The boundaries are exclusive. 72 // The boundaries are exclusive.
56 static const double kLowerBoundary = -1e21; 73 static const double kLowerBoundary = -1e21;
57 static const double kUpperBoundary = 1e21; 74 static const double kUpperBoundary = 1e21;
58 // TODO(floitsch): remove the UNIQUE_ZERO flag when the test is updated. 75 // TODO(floitsch): remove the UNIQUE_ZERO flag when the test is updated.
59 static const int kConversionFlags = 76 static const int kConversionFlags =
60 double_conversion::DoubleToStringConverter::UNIQUE_ZERO; 77 double_conversion::DoubleToStringConverter::NO_FLAGS;
61 const int kBufferSize = 128; 78 const int kBufferSize = 128;
62 // The output contains the sign, at most kMaxDigitsBeforePoint digits, 79 // The output contains the sign, at most kMaxDigitsBeforePoint digits,
63 // the decimal point followed by at most fraction_digits digits plus the \0. 80 // the decimal point followed by at most fraction_digits digits plus the \0.
64 ASSERT(kBufferSize >= 1 + kMaxDigitsBeforePoint + 1 + kMaxFractionDigits + 1); 81 ASSERT(kBufferSize >= 1 + kMaxDigitsBeforePoint + 1 + kMaxFractionDigits + 1);
65 82
66 if (d <= kLowerBoundary || d >= kUpperBoundary) { 83 if (d <= kLowerBoundary || d >= kUpperBoundary) {
67 return false; 84 return false;
68 } 85 }
69 if (fraction_digits < kMinFractionDigits || 86 if (fraction_digits < kMinFractionDigits ||
70 fraction_digits > kMaxFractionDigits) { 87 fraction_digits > kMaxFractionDigits) {
(...skipping 13 matching lines...) Expand all
84 if (!status) return false; 101 if (!status) return false;
85 int length = builder.position(); 102 int length = builder.position();
86 result ^= String::New(reinterpret_cast<uint8_t*>(builder.Finalize()), length); 103 result ^= String::New(reinterpret_cast<uint8_t*>(builder.Finalize()), length);
87 return true; 104 return true;
88 } 105 }
89 106
90 107
91 bool DoubleToStringAsExponential(double d, 108 bool DoubleToStringAsExponential(double d,
92 int fraction_digits, 109 int fraction_digits,
93 String& result) { 110 String& result) {
94 static const int kMinFractionDigits = 0; 111 static const int kMinFractionDigits = -1; // -1 represents shortest mode.
95 static const int kMaxFractionDigits = 20; 112 static const int kMaxFractionDigits = 20;
96 static const int kConversionFlags = 113 static const int kConversionFlags =
97 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN; 114 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN;
98 const int kBufferSize = 128; 115 const int kBufferSize = 128;
99 // The output contains the sign, at most 1 digits, the decimal point followed 116 // The output contains the sign, at most 1 digits, the decimal point followed
100 // by at most kMaxFractionDigits digits, the exponent-character, the 117 // by at most kMaxFractionDigits digits, the exponent-character, the
101 // exponent-sign and three exponent digits plus \0. 118 // exponent-sign and three exponent digits plus \0.
102 ASSERT(kBufferSize >= 1 + 1 + kMaxFractionDigits + 1 + 1 + 3 + 1); 119 ASSERT(kBufferSize >= 1 + 1 + kMaxFractionDigits + 1 + 1 + 3 + 1);
103 120
104 if (!(kMinFractionDigits <= fraction_digits && 121 if (fraction_digits < kMinFractionDigits ||
105 fraction_digits <= kMaxFractionDigits)) { 122 fraction_digits > kMaxFractionDigits) {
106 return false; 123 return false;
107 } 124 }
108 125
109 const double_conversion::DoubleToStringConverter converter( 126 const double_conversion::DoubleToStringConverter converter(
110 kConversionFlags, 127 kConversionFlags,
111 kDoubleToStringCommonInfinitySymbol, 128 kDoubleToStringCommonInfinitySymbol,
112 kDoubleToStringCommonNaNSymbol, 129 kDoubleToStringCommonNaNSymbol,
113 kDoubleToStringCommonExponentChar, 130 kDoubleToStringCommonExponentChar,
114 0, 0, 0, 0); // Last four values are ignored in exponential mode. 131 0, 0, 0, 0); // Last four values are ignored in exponential mode.
115 132
116 UNIMPLEMENTED(); 133 char buffer[kBufferSize];
117 return false; 134 double_conversion::StringBuilder builder(buffer, kBufferSize);
135 bool status = converter.ToExponential(d, fraction_digits, &builder);
136 if (!status) return false;
137 int length = builder.position();
138 result ^= String::New(reinterpret_cast<uint8_t*>(builder.Finalize()), length);
139 return true;
118 } 140 }
119 141
120 142
121 bool DoubleToStringAsPrecision(double d, int precision, String& result) { 143 bool DoubleToStringAsPrecision(double d, int precision, String& result) {
122 static const int kMinPrecisionDigits = 1; 144 static const int kMinPrecisionDigits = 1;
123 static const int kMaxPrecisionDigits = 21; 145 static const int kMaxPrecisionDigits = 21;
124 static const int kMaxLeadingPaddingZeroes = 6; 146 static const int kMaxLeadingPaddingZeroes = 6;
125 static const int kMaxTrailingPaddingZeroes = 0; 147 static const int kMaxTrailingPaddingZeroes = 0;
126 static const int kConversionFlags = 148 static const int kConversionFlags =
127 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN; 149 double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN;
128 const int kBufferSize = 128; 150 const int kBufferSize = 128;
129 // The output contains the sign, the decimal point, precision digits, 151 // The output contains the sign, the decimal point, precision digits,
130 // the exponent-character, the exponent-sign, three exponent digits 152 // the exponent-character, the exponent-sign, three exponent digits
131 // plus the \0. 153 // plus the \0.
132 ASSERT(kBufferSize >= 1 + 1 + kMaxPrecisionDigits + 1 + 1 + 3 + 1); 154 ASSERT(kBufferSize >= 1 + 1 + kMaxPrecisionDigits + 1 + 1 + 3 + 1);
133 155
134 if (!(kMinPrecisionDigits <= precision && precision <= kMaxPrecisionDigits)) { 156 if (!(kMinPrecisionDigits <= precision && precision <= kMaxPrecisionDigits)) {
135 return false; 157 return false;
136 } 158 }
137 159
138 const double_conversion::DoubleToStringConverter converter( 160 const double_conversion::DoubleToStringConverter converter(
139 kConversionFlags, 161 kConversionFlags,
140 kDoubleToStringCommonInfinitySymbol, 162 kDoubleToStringCommonInfinitySymbol,
141 kDoubleToStringCommonNaNSymbol, 163 kDoubleToStringCommonNaNSymbol,
142 kDoubleToStringCommonExponentChar, 164 kDoubleToStringCommonExponentChar,
143 0, 0, // Ignored in precision mode. 165 0, 0, // Ignored in precision mode.
144 kMaxLeadingPaddingZeroes, 166 kMaxLeadingPaddingZeroes,
145 kMaxTrailingPaddingZeroes); 167 kMaxTrailingPaddingZeroes);
146 168
147 UNIMPLEMENTED(); 169 char buffer[kBufferSize];
148 return false; 170 double_conversion::StringBuilder builder(buffer, kBufferSize);
171 bool status = converter.ToPrecision(d, precision, &builder);
172 if (!status) return false;
173 int length = builder.position();
174 result ^= String::New(reinterpret_cast<uint8_t*>(builder.Finalize()), length);
175 return true;
149 } 176 }
150 177
151 } // namespace dart 178 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698