Flutter Engine
The Flutter Engine
double_conversion.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
6
7#include "../../third_party/double-conversion/src/double-conversion.h"
8
9#include "vm/exceptions.h"
10#include "vm/globals.h"
11#include "vm/object.h"
12
13namespace dart {
14
15static constexpr char kExponentChar = 'e';
16static constexpr const char* kInfinitySymbol = "Infinity";
17static constexpr const char* kNaNSymbol = "NaN";
18
19void DoubleToCString(double d, char* buffer, int buffer_size) {
20 const int kDecimalLow = -6;
21 const int kDecimalHigh = 21;
22
23 // The output contains the sign, at most kDecimalHigh - 1 digits,
24 // the decimal point followed by a 0 plus the \0.
25 ASSERT(buffer_size >= 1 + (kDecimalHigh - 1) + 1 + 1 + 1);
26 // Or it contains the sign, a 0, the decimal point, kDecimalLow '0's,
27 // 17 digits (the precision needed for doubles), plus the \0.
28 ASSERT(buffer_size >= 1 + 1 + 1 + kDecimalLow + 17 + 1);
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
31 // sign, at most three exponent digits, plus the \0.
32 ASSERT(buffer_size >= 1 + 17 + 1 + 1 + 1 + 3 + 1);
33
34 const int kConversionFlags =
39
41 kConversionFlags, kInfinitySymbol, kNaNSymbol, kExponentChar, kDecimalLow,
42 kDecimalHigh, 0,
43 0); // Last two values are ignored in shortest mode.
44
46 bool status = converter.ToShortest(d, &builder);
47 ASSERT(status);
48 char* result = builder.Finalize();
50}
51
52StringPtr DoubleToStringAsFixed(double d, int fraction_digits) {
53 const int kMinFractionDigits = 0;
54 const int kMaxFractionDigits = 20;
55 const int kMaxDigitsBeforePoint = 20;
56 // The boundaries are exclusive.
57 const double kLowerBoundary = -1e21;
58 const double kUpperBoundary = 1e21;
59 // TODO(floitsch): remove the UNIQUE_ZERO flag when the test is updated.
60 const int kConversionFlags =
62 const int kBufferSize = 128;
63
64 USE(kMaxDigitsBeforePoint);
65 USE(kMaxFractionDigits);
66 USE(kLowerBoundary);
67 USE(kUpperBoundary);
68 USE(kMinFractionDigits);
69 USE(kMaxFractionDigits);
70 // The output contains the sign, at most kMaxDigitsBeforePoint digits,
71 // the decimal point followed by at most fraction_digits digits plus the \0.
72 ASSERT(kBufferSize >= 1 + kMaxDigitsBeforePoint + 1 + kMaxFractionDigits + 1);
73
74 ASSERT(kLowerBoundary < d && d < kUpperBoundary);
75
76 ASSERT(kMinFractionDigits <= fraction_digits &&
77 fraction_digits <= kMaxFractionDigits);
78
80 kConversionFlags, kInfinitySymbol, kNaNSymbol, kExponentChar, 0, 0, 0,
81 0); // Last four values are ignored in fixed mode.
82
83 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize);
84 buffer[kBufferSize - 1] = '\0';
86 bool status = converter.ToFixed(d, fraction_digits, &builder);
87 ASSERT(status);
88 return String::New(builder.Finalize());
89}
90
91StringPtr DoubleToStringAsExponential(double d, int fraction_digits) {
92 const int kMinFractionDigits = -1; // -1 represents shortest mode.
93 const int kMaxFractionDigits = 20;
94 const int kConversionFlags =
96 const int kBufferSize = 128;
97
98 USE(kMinFractionDigits);
99 USE(kMaxFractionDigits);
100 // The output contains the sign, at most 1 digits, the decimal point followed
101 // by at most kMaxFractionDigits digits, the exponent-character, the
102 // exponent-sign and three exponent digits plus \0.
103 ASSERT(kBufferSize >= 1 + 1 + kMaxFractionDigits + 1 + 1 + 3 + 1);
104
105 ASSERT(kMinFractionDigits <= fraction_digits &&
106 fraction_digits <= kMaxFractionDigits);
107
109 kConversionFlags, kInfinitySymbol, kNaNSymbol, kExponentChar, 0, 0, 0,
110 0); // Last four values are ignored in exponential mode.
111
112 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize);
113 buffer[kBufferSize - 1] = '\0';
115 bool status = converter.ToExponential(d, fraction_digits, &builder);
116 ASSERT(status);
117 return String::New(builder.Finalize());
118}
119
120StringPtr DoubleToStringAsPrecision(double d, int precision) {
121 const int kMinPrecisionDigits = 1;
122 const int kMaxPrecisionDigits = 21;
123 const int kMaxLeadingPaddingZeroes = 6;
124 const int kMaxTrailingPaddingZeroes = 0;
125 const int kConversionFlags =
127 const int kBufferSize = 128;
128
129 USE(kMinPrecisionDigits);
130 USE(kMaxPrecisionDigits);
131 // The output contains the sign, a potential leading 0, the decimal point,
132 // at most kMax{Leading|Trailing} padding zeroes, precision digits,
133 // the exponent-character, the exponent-sign, three exponent digits
134 // plus the \0.
135 // Note that padding and exponent are exclusive. We still add them up.
136 ASSERT(kBufferSize >= 1 + 1 + 1 + kMaxLeadingPaddingZeroes +
137 kMaxTrailingPaddingZeroes + kMaxPrecisionDigits +
138 1 + 1 + 3 + 1);
139
140 ASSERT(kMinPrecisionDigits <= precision && precision <= kMaxPrecisionDigits);
141
143 kConversionFlags, kInfinitySymbol, kNaNSymbol, kExponentChar, 0,
144 0, // Ignored in precision mode.
145 kMaxLeadingPaddingZeroes, kMaxTrailingPaddingZeroes);
146
147 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize);
148 buffer[kBufferSize - 1] = '\0';
150 bool status = converter.ToPrecision(d, precision, &builder);
151 ASSERT(status);
152 return String::New(builder.Finalize());
153}
154
155bool CStringToDouble(const char* str, intptr_t length, double* result) {
156 if (length == 0) {
157 return false;
158 }
159
163
164 int parsed_count = 0;
165 *result =
166 converter.StringToDouble(str, static_cast<int>(length), &parsed_count);
167 return (parsed_count == length);
168}
169
170IntegerPtr DoubleToInteger(Zone* zone, double val) {
171 if (isinf(val) || isnan(val)) {
172 const Array& args = Array::Handle(zone, Array::New(1));
173 args.SetAt(0, String::Handle(zone, String::New("Infinity or NaN toInt")));
175 }
176 int64_t ival = 0;
177 if (val <= static_cast<double>(kMinInt64)) {
178 ival = kMinInt64;
179 } else if (val >= static_cast<double>(kMaxInt64)) {
180 ival = kMaxInt64;
181 } else { // Representable in int64_t.
182 ival = static_cast<int64_t>(val);
183 }
184 return Integer::New(ival);
185}
186
187} // namespace dart
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static const size_t kBufferSize
Definition: SkString.cpp:27
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.h:10959
static DART_NORETURN void ThrowByType(ExceptionType type, const Array &arguments)
Definition: exceptions.cc:1052
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition: object.cc:22984
static Object & Handle()
Definition: object.h:407
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
ElementType * Alloc(intptr_t length)
#define ASSERT(E)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
size_t length
string converter
Definition: cacheimages.py:19
Definition: dart_vm.cc:33
constexpr int64_t kMaxInt64
Definition: globals.h:486
constexpr int64_t kMinInt64
Definition: globals.h:485
StringPtr DoubleToStringAsPrecision(double d, int precision)
void DoubleToCString(double d, char *buffer, int buffer_size)
bool CStringToDouble(const char *str, intptr_t length, double *result)
IntegerPtr DoubleToInteger(Zone *zone, double val)
StringPtr DoubleToStringAsFixed(double d, int fraction_digits)
StringPtr DoubleToStringAsExponential(double d, int fraction_digits)
static constexpr const char * kInfinitySymbol
static void USE(T &&)
Definition: globals.h:618
static constexpr const char * kNaNSymbol
static constexpr char kExponentChar
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126